【问题标题】:Camera rotation jitters after a certain threshold (video)特定阈值后相机旋转抖动(视频)
【发布时间】:2021-05-13 05:02:56
【问题描述】:

所以我有这个设置:

  1. 相机旋转被限制在 Y 轴上。只能左右旋转-75到75度,旋转由鼠标控制。

  2. 玩家身体可以围绕它的 Y 轴旋转,并且它的 Y 旋转值被添加到 -75 和 75 度的相机夹子中,以保持玩家身体前方的相机旋转空间。示例:如果玩家在 Y 轴上旋转 90 度,则钳位值将变为 15 度和 165 度。

当玩家身体在 Y 轴上超过 359 度时会出现问题,因为相机钳位值会从 284 和 434 跳回到 -75 和 75,这会导致相机移动时出现明显的卡顿。我怎样才能消除这个快照?

Video example - Note the camera clamps (Limit L, Limit R) in the MouseLook script after 00:40

*handleBodyRotation 方法只是将玩家的身体旋转到面对作为相机子对象的红色立方体。

public class MouseLook : MonoBehaviour
{
    public Transform CameraBox;
    public Transform lookAtPivot;
    public Transform lookAtObject;
    public Transform playerBody;
 
    public float sensitivity;
    public float bodyRotSpeed;
 
    float xRotation = 0f;
    float yRotation = 0f;
    public float limitL;
    public float limitR;
 
    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
    }
 
    void handleCamRotation()
    {
        float mouseX = Input.GetAxis("Mouse X") * sensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * sensitivity * Time.deltaTime;
 
        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, -45, 35);
 
        yRotation += mouseX;
        yRotation = Mathf.Clamp(yRotation, limitL, limitR);
 
        //Handle and clamp Camera, lookAtPivot, and lookAtObject rotation
        transform.rotation = Quaternion.Euler(xRotation, yRotation, 0f);
 
        //Handle left limit and right limit
        limitL = -75 + playerBody.transform.rotation.eulerAngles.y;
        limitR = 75 + playerBody.transform.rotation.eulerAngles.y;
       
    }
 
    void handleBodyRotation()
    {
        Quaternion targetRotation = Quaternion.Euler(playerBody.transform.rotation.eulerAngles.x, lookAtObject.transform.rotation.eulerAngles.y, playerBody.transform.rotation.eulerAngles.z);
        playerBody.transform.localRotation = Quaternion.Lerp(playerBody.transform.localRotation, targetRotation, bodyRotSpeed * Time.deltaTime);
    }
 
    void Update()
    {
        //Camera Rotation (clamped)
        handleCamRotation();
 
        //Body Rotation
        if (Input.GetKey(KeyCode.W))
        {
            handleBodyRotation();
        }
    }
}

【问题讨论】:

    标签: c# unity3d camera rotation euler-angles


    【解决方案1】:

    你的问题是Transform.eulerAngles的值

    当您阅读 .eulerAngles 属性时,Unity 会将四元数的内部旋转表示转换为欧拉角。因为,使用欧拉角表示任何给定旋转的方法不止一种,因此您读出的值可能与您分配的值完全不同。如果您尝试逐渐增加值以生成动画,这可能会导致混淆。

    特别是 eulerAngles 将始终返回一个介于 0359.9999... 之间的值!

    你自己说它会跳转到 284434,然后返回到 -7575

    为什么?

    因为

    • 359 - 75284359 + 75434
    • 0 - 75-750 + 7575

    您的eulerAngles.y 值接近于359.999... 的结束点 0


    我认为您必须将这些值环绕起来,例如

    limitL = -75 + playerBody.transform.rotation.eulerAngles.y;
    limitR = 75 + playerBody.transform.rotation.eulerAngles.y;
    
    if(limitR > 360) limitR -= 360;
    if(limitR < 0) limitR += 360;
    
    if(limitL > 360) limitL -= 360;
    if(limitL < 0) limitL += 360;
      
    

    不确定,但我想你也必须像这样夹住

    if(limitR > limitL)
    {
        yRotation = Mathf.Clamp(yRotation, limitL, limitR);
    }
    else
    {
        yRotation = Mathf.Clamp(yRotation, limitR, limitL);
    }
    

    不知道 Unity 是如何处理这种情况的 .. 可能是多余的。


    注意:在智能手机上输入,但我希望思路清晰

    【讨论】:

    • 感谢您的回复@derHugo,但不幸的是,该解决方案不起作用,我猜是因为夹具仍然依赖于 playerBody eulerAngles.y,所以当超过 360 度时,我得到类似的结果.有没有其他方法可以返回或跟踪 playerBody Y 旋转超过 360 度,同时能够使用我的常量(-75 和 75)增加它?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多