You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何消除Unity中攀爬梯子时相机旋转的“跳变”问题?

解决攀爬时相机旋转跳变问题

问题根源

  1. 进入攀爬时跳转到(0,0,0):xRotation和yRotation默认初始值为0,首次进入攀爬逻辑时直接用这两个值设置相机旋转,导致从当前旋转跳转到全局0点。
  2. 退出攀爬时跳变:退出后相机的常规旋转逻辑(如自由视角)仍沿用攀爬过程中最后更新的xRotation和yRotation,没有衔接退出时的实际相机旋转状态。

修复方案

在你的MouseCamera脚本中添加状态检测,在攀爬状态切换的瞬间同步旋转变量与相机当前实际旋转值:

// 新增变量记录上一帧的攀爬状态
private bool wasClimbingLastFrame = false;

void Update()
{
    if (climbing.climbing)
    {
        // 首次进入攀爬状态时,同步当前相机旋转到x/yRotation
        if (!wasClimbingLastFrame)
        {
            Vector3 currentEuler = transform.eulerAngles;
            // 将Unity 0-360的欧拉角转换为-180到180范围,适配clamp逻辑
            xRotation = currentEuler.x > 180 ? currentEuler.x - 360 : currentEuler.x;
            yRotation = currentEuler.y > 180 ? currentEuler.y - 360 : currentEuler.y;
        }

        // 原有攀爬旋转逻辑
        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
        float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
        
        xRotation -= mouseY;
        yRotation += mouseX;

        xRotation = Mathf.Clamp(xRotation, -90f, 90f);
        yRotation = Mathf.Clamp(yRotation, -35f, 35f);

        transform.eulerAngles = new Vector3(xRotation, yRotation, 0f); 
        player.transform.Rotate(Vector3.up * mouseX);
    }
    else
    {
        // 退出攀爬状态时,同步当前相机旋转到x/yRotation,保证后续视角衔接
        if (wasClimbingLastFrame)
        {
            Vector3 currentEuler = transform.eulerAngles;
            xRotation = currentEuler.x > 180 ? currentEuler.x - 360 : currentEuler.x;
            yRotation = currentEuler.y > 180 ? currentEuler.y - 360 : currentEuler.y;
        }

        // 这里放置你的常规相机旋转逻辑(自由视角代码)
        // 例如:
        // float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity;
        // float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity;
        // xRotation -= mouseY;
        // yRotation += mouseX;
        // xRotation = Mathf.Clamp(xRotation, -90f, 90f);
        // transform.eulerAngles = new Vector3(xRotation, yRotation, 0f);
        // player.transform.Rotate(Vector3.up * mouseX);
    }

    // 更新上一帧攀爬状态
    wasClimbingLastFrame = climbing.climbing;
}

关键细节

  • 转换欧拉角范围:Unity返回的transform.eulerAngles是0-360度,而我们的旋转变量用的是-180到180度,必须做转换,否则Mathf.Clamp会导致错误的旋转跳变。
  • 状态切换检测:通过wasClimbingLastFrame变量精准捕捉攀爬状态的切换瞬间,只在切换时同步旋转值,避免每帧重复同步影响性能。

内容的提问来源于stack exchange,提问作者dangoqut132

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 21:37:38