使用扭矩稳定气垫船刚体直立

Kat*_*ime 3 c# unity-game-engine

我目前正在创建一款涉及悬停自行车的游戏。当自行车与物体碰撞时,它的角度会自然改变。我希望创建某种方法让它趋向于 0。这是我尝试过的:

if (hoverbike.rotation.x != 0 || hoverbike.rotation.z != 0)
        {
            hoverbike.AddTorque(x: Mathf.MoveTowardsAngle(hoverbike.rotation.x, 0, 0.01f), y: hoverbike.rotation.y, z: Mathf.MoveTowardsAngle(hoverbike.rotation.z, 0, 0.01f));
        }

        transform.Rotate(0.0f, -Input.GetAxis("Mouse X") * 0.5f, 0.0f);
Run Code Online (Sandbox Code Playgroud)

很难解释它在做什么,因为我不明白它在做什么,它似乎在旋转。如果有兴趣的话,这是我的其余代码:https://pastebin.com/kzMDQMVF,这是一团糟,但我仍在学习如何使用 Unity。

哦,角度 y 不应该趋于 0,因为那是水平角。

Ruz*_*ihm 5

您可以使用以下命令确定将气垫船从当前向上旋转到世界向上的四元数Quaternion.FromToRotation

Rigidbody hoverRB; // hovercraft's rigidbody

Quaternion deltaQuat = Quaternion.FromToRotation(hoverRB.transform.up, Vector3.up);
Run Code Online (Sandbox Code Playgroud)

然后使用Quaternion.ToAngleAxis将其转换为角度和轴:

Vector3 axis;
float angle
deltaQuat.ToAngleAxis(out angle, out axis);
Run Code Online (Sandbox Code Playgroud)

然后,取消一些现有的旋转速度,以便最终达到目标:

float dampenFactor = 0.8f; // this value requires tuning
hoverRB.AddTorque(-hoverRB.angularVelocity * dampenFactor, ForceMode.Acceleration);
Run Code Online (Sandbox Code Playgroud)

然后沿着我们之前找到的轴施加一些扭矩,按剩余角度缩放:

float adjustFactor = 0.5f; // this value requires tuning
hoverRB.AddTorque(axis.normalized * angle * adjustFactor, ForceMode.Acceleration);
Run Code Online (Sandbox Code Playgroud)

Rigidbody 使用的弧度和度数之间的任何转换ToAngleAxis对于常量都是多余的float,因此不必太担心。

FixedUpdate确保这一切都在(或称为/及时运行的函数)中完成FixedUpdate,因为扭矩的方向可能需要从一个物理步骤更改为另一个物理步骤。所以,总共:

Rigidbody hoverRB; // hovercraft's rigidbody

...

void FixedUpdate() 
{    
    Quaternion deltaQuat = Quaternion.FromToRotation(hoverRB.transform.up, Vector3.up);

    Vector3 axis;
    float angle
    deltaQuat.ToAngleAxis(out angle, out axis);

    float dampenFactor = 0.8f; // this value requires tuning
    hoverRB.AddTorque(-hoverRB.angularVelocity * dampenFactor, ForceMode.Acceleration);

    float adjustFactor = 0.5f; // this value requires tuning
    hoverRB.AddTorque(axis.normalized * angle * adjustFactor, ForceMode.Acceleration);
}
Run Code Online (Sandbox Code Playgroud)