РЕДАКТИРОВАТЬ: Как я выяснил, идентификатор пальца получает тот же номер, что и исходное значение индекса касания, я сделал метод сброса сохраненного идентификатора пальца от отброшенного касания до -1. Полный ответ опубликован.
Я пытаюсь реализовать мультитач-управление двумя пальцами для моей простой стрелялки, где один выстрел пальцем непрерывно влияет на вращение игрока, если его сначала удерживать в заданная область находится ниже на экране, а другая управляет кнопкой съемки, которая также может быть загружена для стрельбы более мощными пулями.
Сначала я попытался сохранить позицию касания, когда 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);
}
}