首页 > 解决方案 > 如何使用四元数统一实现飞机旋转

问题描述

如果有人有更好的问题标题,请告诉我。我在我的游戏中做了一些不同的事情,但这解释了我正在努力解决的问题。

这是我用来尝试更好地理解四元数旋转的代码:

    // verifies that 90° turn on x axis points down (flying downwards)
    // expected : (0, -1, 0)
    // actual   : (0, -1, 0)
    var down = Quaternion.identity * Quaternion.Euler(90, 0, 0) * Vector3.forward;
    var rightRotation = Quaternion.Euler(0, 90, 0);
    
    // verifies that right rotation applied to forward direction results in a right direction
    // expected : (1, 0, 0)
    // actual   : (1, 0, 0)
    var right = rightRotation * Vector3.forward;
    
    // verifies that when flying downwards and doing a right turn it should be pointing right
    // expected : (1, 0, 0)
    // actual   : (0~, 0~, -1)
    var alsoRight = (Quaternion.LookRotation(down, Vector3.forward) * rightRotation) * down;

但是结果向量是 (0, 0, -1) 而不是 (1, 0, 0)。

所以我想这里的问题是我如何围绕相对轴而不是世界 x 轴旋转四元数?

如果我们假设最初的零旋转是从后面我会期望它飞向正确的向量,同时显示它的腹部。

我哪里错了?

标签: unity3dquaternions

解决方案


这个脚本帮助我理解了如何去做以及为什么我之前的尝试没有奏效:

public class EulerRotation : MonoBehaviour
{

    public bool x;
    public bool y;
    public bool z;

    void Update()
    {
        if (z)
            transform.rotation = Quaternion.AngleAxis(0.1f, transform.forward) * transform.rotation;
        if (y)
            transform.rotation = Quaternion.AngleAxis(0.1f, transform.up) * transform.rotation;
        if (x)
            transform.rotation = Quaternion.AngleAxis(0.1f, transform.right) * transform.rotation;
    }

    private void FixedUpdate()
    {
        Debug.DrawRay(transform.position, transform.forward * -5, Color.blue);
        Debug.DrawRay(transform.position, transform.right * -5, Color.red);
        Debug.DrawRay(transform.position, transform.up * -5, Color.green);
    }
}

当做 transform.rotation * modifiedrotation 结果总是错误的。在做 modifiedrotation * transform.rotation 时,我确实得到了我期望的结果。

所以使用 Quaternion.AngleAxis 是相对于其当前旋转旋转对象的正确方法,但轴旋转必须乘以当前旋转,而不是相反。


推荐阅读