我如何确定我的汽车变换移动的方向

How can I determine which direction my car transform is moving

我有一辆 transform 的汽车,其标准 CarController 组件来自 UnityStandardAssets.Vehicles

如果我移动汽车并检查来自 CarController 的速度,它对于倒车或加​​速都是正值。

确定变换是朝着 'front' 还是 'back' 移动的正确方法是什么?

查看一些文档后,这是在黑暗中拍摄的照片。

CarController作用于RigidBody,CurrentSpeed是根据速度矢量的大小计算出来的,然后换算成miles per hour。幅度不能为负,因此您需要将汽车的前进方向与刚体的速度矢量进行比较。

如果2个归一化向量的点积为1,则它们是平行的。如果点积是-1,那么它们是相反的。如果为 0,则它们是垂直的。如果是 0.5f,那么它们 大致相同但不完全平行 。如果是-0.5f,那么它们方向大致相反但不完全相反

我的建议是检查汽车的归一化前向矢量与其刚体的归一化速度矢量的点积。如果它大于 0.5f,那么汽车主要是向前移动,如果它小于 -0.5f,那么汽车主要是向后移动。如果它在 -0.5f 和 0.5f 之间,那么汽车主要是侧向打滑。

    Rigidbody rb;
    string dir;

    Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    //Since you'll be working with physics (rigidbody's velocity), you'll be using fixedupdate
    FixedUpdate()
    {
        float dotP = Vector3.Dot(transform.forward.normalized, rb.velocity.normalized);
        if(dotP > 0.5f)
        {
            dir = "forward";
        }
        else if(dotP < -0.5f)
        {
            dir = "reverse";
        }
        else
        {
            dir = "sliding sideways";
        }
    }

为方向设置枚举可能更有价值,或者只为 reverse/forward 使用布尔值。您应该根据自己的需要进行调整。

这段代码是徒手写的,所以请让我知道任何语法错误。

您需要检查两个参数。 rb.velocity 向量和 transform.forward 的第一个 vector.dot 乘积,然后是最小速度阈值。

private void CheckDirection()
{
    var dot = Vector3.Dot(transform.forward, rb.velocity);

    if (rb.velocity.magnitude <= speedThreshold) return;
    
    Debug.Log(dot >= 0 ? "Forward" : "Backward");
}

此代码可以从 Unity 直接粘贴到 CarController 脚本中。

正如 Erik Overflow 所指出的,一个很好的建议是实现一个继承 CarController 的自定义控制器。这样当Unity更新包时你的代码就不会消失

public const string DIRECTION_FORWARD = "forward";
public const string DIRECTION_REVERSE = "reverse";
public const string DIRECTION_SIDESLIDE = "sideslide";
public const string DIRECTION_STATIC = "static";

public string GetMovementDirection() {
    float dotP = Vector3.Dot(transform.forward, m_Rigidbody.velocity);
    if (dotP > 0.5f) {
        return DIRECTION_FORWARD;
    } else if (dotP < -0.5f) {
        return DIRECTION_REVERSE;
    } else if (CurrentSpeed <= 0.99f) {
        return DIRECTION_STATIC;
    } else {
        return DIRECTION_SIDESLIDE;
    }
}