C# 平滑旋转-四元数

C# 平滑旋转-四元数,c#,unity3d,rotation,quaternions,C#,Unity3d,Rotation,Quaternions,我正在尝试制作第一人称角色控制器,但在平滑外观旋转时遇到了问题。我的LookRotation脚本接受我的鼠标输入并使用它旋转角色。我使用了Quaternion.Slerp()。一旦所需的旋转距离当前旋转超过180度,它将只采用较短的路线(相反的方向)。问题出现在最后两行代码中。有人有办法防止这个问题吗?提前谢谢 #region Variables // Sensitivity variables [Range(0.0f, 10.0f)] public float horizontalSensit

我正在尝试制作第一人称角色控制器,但在平滑外观旋转时遇到了问题。我的
LookRotation
脚本接受我的鼠标输入并使用它旋转角色。我使用了
Quaternion.Slerp()。一旦所需的旋转距离当前旋转超过180度,它将只采用较短的路线(相反的方向)。问题出现在最后两行代码中。有人有办法防止这个问题吗?提前谢谢

#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);
}

不能用四元数和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
将始终找到最短的距离。EULER可以达到您想要的高度(或者更精确地说,达到数据类型允许的高度),因此它没有这个问题

虽然如果继续增加角度,这对普通玩家来说不太可能成为问题,但在这种情况下,数据类型
float
,最终将失去精度。为了避免这种情况,只需从角度和平滑角度减去或添加360的任意倍数(取决于该值是正还是负),该数字足够高,从而不会影响
Lerp


使用此方法获取x轴上的起始角度有一些问题,但与此问题无关,因此任何想知道如何进行此操作的人都必须找到解决该问题的替代源。

您真的需要
四元数.Slerp()
?对于基本旋转,我考虑使用简单快速的
Quaternion.Lerp()
方法
Quaternion.Slerp()
球形插值旋转值,这可能就是问题所在。我看不到对
transform.rotation
的任何引用,但我假设您稍后会在代码中这样做。@MadJlzz感谢您的回复,我可能应该使用Quaternion.Lerp,但这仍然与Quaternion.Slerp有相同的问题。@MadJlzz我还使用
character.localRotation
&
characterCamera.localRotation
来改变旋转(最后两行),因为我身边没有统一体,我无法直接实现您想要的行为,但我已经成功地编写了一个小脚本,在给定旋转速度和阻尼值的情况下执行旋转。(脚本没有经过测试,但希望它能工作)。它应该可以帮助你管理你的问题,因为你必须做的最后一件事是计算你的鼠标所做的旋转,并将其应用到你的游戏对象。编辑:要更改旋转,您应该更改
transform.rotation
的适当性。恐怕您必须修改Lerp以满足您的要求。默认情况下,Lerp将始终选择“较短路线”。