我将使用什么公式将速度与 Unity 的旋转相关联?

What formula would I use to relate velocity to rotation I Unity?

我正在 Unity 中尝试为基于物理的箭头创建脚本。 我的弧线正常,但在整个飞行过程中它仍然笔直向上。 我正在尝试使用 Quaternion.LookRotation 来根据速度 (R = 0 at V = Vinitial, R = 90 at V = 0, and R = 180 at V = -Vinitial) 更改它的旋转,但我一直无法弄清楚我将使用什么公式。 任何帮助将不胜感激。

编辑

在回复的帮助下,我能够让它按预期工作。万一有人偶然发现这个问题寻求帮助,我的最终代码如下所示:

private void Update()
{
    if (ForceSet)
    {
        ForceSet = false;
        initialVelocity = rb.velocity;
        EndAngleOffset = .33f * rb.velocity.y;
    }
    if (stuckTarget == null)
    {
        Vector3 Forward;
        Vector3 Upward;
        if (rb.velocity.y > 0)
        {
            Forward = new Vector3(rb.velocity.x, -((-initialVelocity.y + rb.velocity.y - EndAngleOffset) * (-initialVelocity.y + rb.velocity.y - EndAngleOffset)), rb.velocity.z);
            Upward = new Vector3(0, 1, 0);
        }
        else
        {
            Forward = new Vector3(rb.velocity.x, ((initialVelocity.y + rb.velocity.y + EndAngleOffset) * (initialVelocity.y + rb.velocity.y + EndAngleOffset)), rb.velocity.z);
            Upward = new Vector3(0, -1, 0);
        }
        rb.rotation = Quaternion.LookRotation(Forward, Upward);

}

(当向 'Arrow' 施加发射力时,ForceSet 设置为 true)

如果您有权访问箭头 Rigidbody 组件,则可以访问它的 velocity 属性 并将其 rotation 设置为等于其 velocity.

我建议在对 Rigidbody 的转换进行修改时使用 Rigidbody 方法。这可确保使用 Unity 的物理系统正确更新值。

using UnityEngine;

public class ArrowBehaviour : MonoBehaviour
{
    private Rigidbody rigidbody;

    private void Awake()
    {
        rigidbody = GetComponent<Rigidbody>();
    }

    private void Update()
    {
        rigidbody.rotation = Quaternion.LookRotation(rigidbody.velocity, Vector3.up);
    }
}

根据具体情况,您可能希望将 Update 更改为 FixedUpdate

编辑:

上面的代码中有一个 bug 我修复了;这就是你在凌晨 2 点写它时得到的结果。我会再试一次,看看是否适合你。

在理想情况下,您会 pre-compute 箭头的路径,以便您可以对所需的箭头执行任何程序动画。

您也可以计算一个 X 旋转来代替使用,这将伪造效果。

using UnityEngine;

public class ArrowBehaviour : MonoBehaviour
{
    [SerializeField] private float lookMagnitude = 45.0f;
    [SerializeField] private float velocitySensitivity;

    private Rigidbody rigidbody;

    private void Awake()
    {
        rigidbody = GetComponent<Rigidbody>();
    }

    private void Update()
    {
        // Determine how much we want to fake the rotation by.
        var lookStrength = Mathf.InverseLerp(-velocitySensitivity, velocitySensitivity, rigidbody.velocity)

        var targetEulerAngles = new Vector3(
         Mathf.Lerp(-lookMagnitude, lookMagnitude, lookStrength),
         transform.localEulerAngles.y,
         transform.localEulerAngles.z
        );

        // Rotate the transform
        transform.localEulerAngles = targetEulerAngles;

        // Alternatively, interpolate to the target angle.
        /* transform.localEulerAngles = Vector3.Lerp(
         *  transform.localEulerAngles,
         *  targetEulerAngles,
         *  Time.deltaTime * rotationSpeed
         * );
         */
    }
}

获取变换旋转并将其设置为等于Quaternion.LookRotation(velocity)

应该没问题