对象未按从 Atan2 到四元数的正确方向旋转

Object does not rotate in the correct direction from Atan2 to Quaternion

我正在尝试在其 z 轴上旋转一个对象,给定一个我用 Atan2 函数以一定角度计算的点。然后我创建一个四元数以将其输入到对象的旋转中。然而,它并没有按照假定的正确方向旋转。如果我绘制 Atan2 函数给出的角度图,我会想象一个顺时针角度系统,但如果我绘制应该使我的对象在正确方向上呈现的角度,我会想象一个逆时针系统。使用 Atan2 函数接收的值作为键创建字典的解决方案,它们的值是对象将旋转正确方向的角度。但我仍然不明白发生了什么。我希望有人能帮助我理解它,因为没有比解决但不知道发生了什么更糟糕的解决方案。

public class ArrowMovement : MonoBehaviour
{
    public Vector2Variable currentPlayerDirection;
    public Vector3Variable currentPlayerPosition;
    public InputAxis inputAxis;

    private float anglePassed;
    private Dictionary<float, float> realAngles = new Dictionary<float, float>();

    void Awake()
    {
        realAngles.Add(-135, -135);
        realAngles.Add(-90, 180);
        realAngles.Add(-45, 135);
        realAngles.Add(0, 90);
        realAngles.Add(45, 45);
        realAngles.Add(90, 0);
        realAngles.Add(135, -45);
        realAngles.Add(180, -90);
    }

    void Update()
    {
        Vector3 offsetVector = new Vector3(0.2f, 0.05f, 0);
        transform.position = currentPlayerPosition.Value;

        // Rotation
        float angle = Mathf.Atan2(inputAxis.horizontal, inputAxis.verticall) * Mathf.Rad2Deg;
        Quaternion rotation = Quaternion.Euler(0, 0, realAngles[angle]);
        transform.rotation = rotation;
    }
}

创建字典不是最好的方法,因为它没有考虑您设置的字典之间的角度,因此要从一个图表转换为另一个图表,我会创建一个如下所示的函数:

float ChangeAngleDiagram(float angle) {
    return -(angle + 90f)+180;
}

首先,你应该知道inputAxis是什么。 我可以从你的图表中猜到你期望 inputAxis.verticall == 0 的角度必须为 0。让我们看一下 Mathf.Athan2(y,x) - it is equivalent to arctan(y/x),因此只有当 y 为零时结果才会为零。但是,在您的代码中,Mathf.Atan2(inputAxis.horizontal, inputAxis.verticall) 会在 inputAxis.horizontal == 0 时给出 0 - 它是垂直方向(您的第一个图表)。

第二个问题-旋转方向错误。当其中一个输入轴反转时,可能会发生这种情况。可能 inputAxis 是在相对于您的对象的不同坐标系中测量的,即您的对象的 Z 是您的 inputAxis-Z。反正inputAxis.verticall可以反

float angle = Mathf.Atan2(inputAxis.horizontal, -inputAxis.verticall) * Mathf.Rad2Deg;

此外,您应该避免使用 "creating a dictionary" 或类似方法解决简单的几何问题。即使您不知道 inputAxis 是如何工作的并且结果是错误的 - 分两步来修复它: 1. 固定旋转方向 - 只需反转角度 Quaternion.Euler(0, 0, -angle); 2.固定零位-添加一些静态旋转。在你的情况下是 90 度 Quaternion.Euler(0, 0, 90 - angle)。并且是解决问题的第二种方法。