c# - 在 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);
}
}
解决方案
由于这没有收到任何答案,而且我还没有找到其他方法,因此我将发布我发现可行的方法——即使可能有其他更有效的解决方案。
手指 ID 与触摸的原始索引匹配,可以是 0 或更高。因此,我为每个控制方法保存了一个唯一的整数类型,并用值 -1 对其进行了初始化。当 TouchPhase.Began 的触摸落在为按钮或控制区域之一定义的边界内时,我将记录的手指 ID 值提供给唯一的整数类型,然后由相应的方法使用它来查找触摸期间的索引每一帧,当使用此手指 ID 的触摸返回 TouchPhase.Ended 时,它再次为保存的整数提供 -1 值,在任何触摸中都找不到该值,因此它停止控制方法。
推荐阅读
- c# - 如何从 IChangeSet 中提取单个项目?
- excel - 针对另一个范围过滤的范围的 Excel [标准偏差]
- java - 使用 SpringBoot 的 MongoDb 事务
- java - 如何使用 JavaParser 在同一行添加新语句
- ruby-on-rails - 如何使用 Rails Capybara 检查行为类似于按钮的禁用 div?
- python - M. Zelle's Graphics 的圆弧运动
- javascript - javascript中的动态变化,不会移动我的div
- powershell - 使用用户名获取远程计算机的运行进程
- javascript - 如何从 DOM 元素中删除匿名函数
- android - Admob 横幅 ANR - Android 8.1 (SDK 27)