轴上的统一定位

时间:2018-10-25 04:39:59

标签: c# unity3d

我有一个第一人称刚体胶囊,该胶囊旋转,以便他始终会垂直于重力方向直立。我想将播放器旋转到侧面,以便播放器相机不会垂直旋转。

我的代码是

void Update() {
    FixOrientation();
}

void FixOrientation()
{
    if (trans.up != -GetGravityDirection())
    {
        Quaternion targetRotation = Quaternion.FromToRotation(trans.up, -GetGravityDirection()) * trans.localRotation;
        trans.localRotation = Quaternion.RotateTowards(trans.localRotation, targetRotation, 5f);
    }
}

结果是, current

在上图中,我将重力方向更改为指向天花板。

此代码仅使播放器无论面向哪个位置都沿全局x轴旋转,这意味着当我面向全局向前或向后时,播放器将垂直旋转相机。我想要的是使其在侧面(局部z轴)上旋转。

1 个答案:

答案 0 :(得分:1)

Unity已经有一种确切的方法:Transform.Rotate带有一个带角度和旋转轴的过载。

可能看起来像

// rotation speed in degrees per second
public float RotationSpeed;

void Update()
{
    FixOrientation();
}

void FixOrientation()
{
    if (transform.up != -GetGravityDirection())
    {
        // Get the current angle between the up axis and your negative gravity vector
        var difference = Vector3.Angle(transform.up, -GetGravityDirection());

        // This simply assures you don't overshoot and rotate more than required 
        // to avoid a back-forward loop
        // also use Time.deltaTime for a frame-independent rotation speed
        var maxStep = Mathf.Min(difference, RotationSpeed * Time.deltaTime);

        // you only want ot rotate around local Z axis
        // Space.Self makes sure you use the local axis
        transform.Rotate(0, 0, maxStep, Space.Self);
        }
    }

旁注:

一般来说,直接比较两个向量要小心

trans.up != -GetGravityDirection()

使用0.00001的近似值。在您的情况下,这还是可以的,但为了进行比较,您应该使用

Vector3.Angle(vector1, vector2) > threshold

定义一个更大或更强的阈值