使用 C# 在 Unity 3d 中使用触摸旋转游戏对象

Rotating gameobject using touch in Unity 3d with C#

我正在根据 2 根手指的触摸来旋转游戏对象。我的旋转工作正常,但我遇到了一个奇怪的问题,有时我会用两根手指触摸来开始旋转,但只要我触摸屏幕,对象就会立即旋转。这似乎是随机的,当它这样做时,旋转也似乎是随机的。我认为触摸触发了基于最后位置的旋转,但我的代码应该重置起始位置。

触摸代码在附加到要旋转的对象的脚本中,因此全部在一个文件中。

这是代码。

在 Update 方法中,我检测到它支持触摸并尝试调用 "HandleTouch()"

void Update()
{
    if (Input.touchSupported)
        HandleTouch();
    else
        HandleMouse();
}

HandleTouch 方法

private void HandleTouch()
{
    if (Input.touchCount < 2) return;
    switch (Input.touchCount)
    {
        case 2:
            Touch touch = Input.GetTouch(0);
            if (touch.phase == TouchPhase.Began)
            {
                lastRotPosition = touch.position;
            }
            else if (touch.phase == TouchPhase.Moved)
            {
                Vector3 offset = touch.position - lastRotPosition;
                lastRotPosition = touch.position;
                RotateCamera(offset.x * RotateSpeedTouch, offset.y * RotateSpeedTouch);
            }
            else if (touch.phase == TouchPhase.Ended)
            {
                lastRotPosition = new Vector2();
            }
            break;
    }
}

这是旋转游戏对象的方法

void RotateCamera(float x, float y)
{
    float rotX = x * rotateSpeed * Mathf.Deg2Rad;
    float rotY = y * rotateSpeed * Mathf.Deg2Rad;
    transform.Rotate(Vector3.up, rotX);
    transform.Rotate(Vector3.right, -rotY);
}

感谢您提供的任何帮助或见解。

您没有跟踪 fingerId

因为触摸可能不会以相同的顺序存储:

Furthermore, the continuity of a touch between frame updates can be detected by the device, so a consistent ID number can be reported across frames and used to determine how a particular finger is moving.

...the fingerId property can be used to identify the same touch between frames.

因此,当新手指触摸屏幕时,您的代码可能会看到:

  • 第一个手指触摸,触摸计数 1,跳过代码
  • 第二根手指触摸,是数组中的第二根手指,触摸计数2,开始处理:
    • 第一次触摸有阶段TouchPhase.Moved
    • lastRotPosition 当前为零(由于默认值或由于先前的 TouchPhase.Ended
    • touch.position - lastRotPosition 计算为非零(发生大旋转)

当它正常工作时,您会看到:

  • 第一个手指触摸,触摸计数 1,跳过代码
  • 第二根手指触摸,是数组中的根手指,触摸计数2,开始处理:
    • 第一次触摸有阶段TouchPhase.Begin
    • lastRotPosition 更新为触摸的位置
    • 下一帧 touch.position - lastRotPosition 的计算结果接近于零(发生小的旋转)