2017-03-21 15 views
1

私は一人称キャラクターコントローラーを作ろうとしていますが、私のルックローテーションをスムーズにする問題があります。私のLookRotationスクリプトは私のマウス入力を受け取り、それを使って文字を回転させます。私はQuaternion.Slerp()を使用して問題があるが、私の見て回転を滑らかにするためにQuaternion.Slerp()を使用していました。目的の回転が現在の回転から180度より大きくなると、より短いルート(逆の方法)になります。問題はコードの最後の2行です。誰にもこの問題を防ぐ方法がありますか?前もって感謝します!スムーズローテーション - 四元数

#region Variables 
// Sensitivity variables 
[Range(0.0f, 10.0f)] public float horizontalSensitivity = 2.0f, verticalSensitivity = 2.0f; 

// Smoothing Variables 
[Range(0.0f, 30.0f)] public float smoothAmount = 5.0f; 

// Character rotation variables 
private Quaternion characterTargetRotation; 
private Quaternion cameraTargetRotation; 

public Transform character; 
public Transform characterCamera;  
#endregion 

private void Update() 
{ 
    float horizontalRotation = Input.GetAxis("Mouse X") * horizontalSensitivity; 
    float verticalRotation = Input.GetAxis("Mouse Y") * verticalSensitivity; 

    characterTargetRotation *= Quaternion.Euler(0.0f, horizontalRotation, 0.0f); 
    cameraTargetRotation *= Quaternion.Euler(-verticalRotation, 0.0f, 0.0f); 

    character.localRotation = Quaternion.Lerp(_character.localRotation, characterTargetRotation, smoothAmount * Time.deltaTime); 
    characterCamera.localRotation = Quaternion.Lerp(_characterCamera.localRotation, cameraTargetRotation, smoothAmount * Time.deltaTime); 
} 
+1

本当に 'Quaternion.Slerp()'が必要ですか?基本的なローテーションについては、単純で早いフォワード 'Quaternion.Lerp()'メソッドを使うことを考えていました。 'Quaternion.Slerp()'は回転値を球形に補間しますが、それは問題の可能性があります。 'transform.rotation'への参照はありませんが、後でコードで行うことを前提としています。 – MadJlzz

+0

@MadJlzz応答のおかげで、私はおそらくQuaternion.Lerpを使用する必要がありますが、それでもQuaternion.Slerpと同じ問題が発生します。 – jozza710

+0

@MadJlzzまた、 'character.localRotation'と' characterCamera.localRotation'を使ってローテーションを変更します(最後の2行) – jozza710

答えて

1

QuaternionsとLerpを使用して行うことはできません。オイラー角を使用してこれを解決しました。この方法を使用

horizontalAngle += (Input.GetAxis("Mouse X") * horizontalSensitivity); 
    verticalAngle += (-Input.GetAxis("Mouse Y") * verticalSensitivity); 

    horizontalSmoothAngle = Mathf.Lerp(horizontalSmoothAngle, horizontalRotation, smoothAmount * Time.deltaTime); 
    verticalSmoothAngle = Mathf.Lerp(verticalSmoothAngle , verticalRotation, smoothAmount * Time.deltaTime); 

    horizontalRotation = Quaternion.Euler(0, smoothRotation ? horizontalSmoothAngle: horizontalAngle, 0); 
    verticalRotation = Quaternion.Euler(smoothRotation ? verticalSmoothAngle : verticalAngle, 0, 0); 

は、あなたが対処しなければならない別の問題を作成しますが、四元数を使用してLerpを解決することがカント問題があります。上記のように、Lerpは常に最短距離を見つけるでしょう。オイラーは、必要なだけ高い(またはデータ型が許す限り正確に)行くことができるため、この問題はありません。

アングルに追加し続けると通常プレーヤーにとって問題になることはありませんが、この場合のデータタイプはfloatであり、結果的に精度が低下します。これを回避するには、Lerpに影響しないように、角度からの360の任意の倍数と平滑化された角度を単純にマイナスまたは加算します(値が正か負かによって異なります)。

この方法を使用してx軸の開始角度を取得するにはいくつかの問題がありますが、この質問には関係ありません。その方法を知りたい方は、その問題の解決策の代替ソースを見つける必要があります。

関連する問題