首页 > 解决方案 > 在 Unity 中如何正确使用 fingerId?

问题描述

编辑: 当我发现手指 ID 与触摸的原始索引值相同时,我做了一个方法,将保存的手指 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#androidunity3dtouch

解决方案


由于这没有收到任何答案,而且我还没有找到其他方法,因此我将发布我发现可行的方法——即使可能有其他更有效的解决方案。

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


推荐阅读