如何在Unity中正确使用fingerId?

问题描述 投票:-1回答:1

EDIT 由于我发现finger ID得到的数字与触控的原始索引值相同,所以我做了一个方法,将废弃触控中保存的finger ID重置为-1。发了一个完整的答案。


我正在尝试为我的简单射击游戏实现2个手指的多点触控,其中一个手指射击如果先在屏幕下方的定义区域按住,会持续影响玩家的旋转,另一个手指控制射击按钮,也可以装上更多的子弹。

一开始我试着把TouchPhase=Began时的触摸位置存储在一个Vector3数组中,有两个地方,其他类检查数组中的数值是否以及哪一个符合规则开始它们的活动。问题是,如果早先的手指被抬起,手指索引似乎会下降,所以如果我按下例如瞄准->射击按钮,然后抬起瞄准,瞄准按钮就会卡在加载中,因为它试图跟踪触摸(1),而实际上变成了(0)。

解决方法似乎应该是使用fingerId,它可以为触摸产生一个一致的数字,而不管它的索引是什么。问题是--我写的东西比以前更糟糕。即使我按错了地方,它也会激活函数,所以即使不该按的地方,if 语句似乎也符合要求。代码有什么问题?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TouchControls : MonoBehaviour
{
    public static int aimID;
    public static int shootID;
    // Start is called before the first frame update
    void Start()
    {
        aimID = 0;
        shootID = 0;
    }

    // Update is called once per frame
    void Update()
    {
        for (int i = 0; i < Input.touchCount && i < 2; i++)
        {
            if (Input.GetTouch(i).phase == TouchPhase.Began)
            {
                Vector2 pos = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position);
                if (pos.x == Mathf.Clamp(pos.x, -2.5f * SceneScale.ratio, 2.5f * SceneScale.ratio) &&
                    pos.y <= Camera.main.ScreenToWorldPoint(new Vector3(0, 0, 0)).y + (2 * SceneScale.ratio))
                {
                    aimID = Input.GetTouch(i).fingerId;
                }
                else if (Vector2.Distance(pos, ShotButton.position) <= ShotButton.scale.x)
                {
                    shootID = Input.GetTouch(i).fingerId;
                }
            }
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Android;

public class ShotButton : MonoBehaviour
{
    public static bool[] time;
    static public Vector3 scale;
    static public Vector2 position;
    // Start is called before the first frame update
    void Start()
    {
        scale = gameObject.transform.localScale;
        position = new Vector2(gameObject.transform.position.x, gameObject.transform.position.y);
        time = new bool[2];
        time[0] = false;
        time[1] = false;
    }

    // Update is called once per frame
    public void FixedUpdate()
    {
        for (int i = 0; i < Input.touchCount && i < 2; i++)
        {
            time[i] = false;
            if (Input.GetTouch(i).fingerId == TouchControls.shootID)
            {
                time[i] = true;
            }
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public GameObject player;
    public static bool isDead = false;

    public float rot;
    // Start is called before the first frame update
    void Start()
    {
    }

    // Update is called once per frame
    public void FixedUpdate()
    {
        for (int i = 0; i < Input.touchCount && i < 2; i++)
        {
            if (Input.GetTouch(i).fingerId == TouchControls.aimID)
            {
                rot = Camera.main.ScreenToWorldPoint(Input.GetTouch(i).position).x * 80 / (2.5f * SceneScale.ratio);
            }
        }
        rot = Mathf.Clamp(rot, -80, 80);
        player.transform.rotation = Quaternion.Euler(0, 0, rot);
    }
}
c# android unity3d touch
1个回答
0
投票

由于这个问题没有得到答案,我也没有找到不同的方法,所以我把我发现的工作方法贴出来--尽管可能还有其他更有效的解决方案。

手指ID与触摸的原始索引相匹配,可以是0或以上。所以我为每个控制方法保存了一个唯一的整数类型,并将其初始化为值-1,当TouchPhase.Began的触控落在为其中一个按钮或控制区域定义的边界内时,我给这个唯一的整数类型记录的手指ID值,然后由相应的方法来寻找每一帧中触控所在的索引,当带有这个手指ID的触控返回TouchPhase.Ended时,它再次给保存的整数值-1,在任何触控中都找不到这个值,因此它停止了控制方法。

© www.soinside.com 2019 - 2024. All rights reserved.