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

Unity相机触左边界瞬移至右边界问题求助(转向限制>90时)

问题修复:相机旋转限制瞬移及视角偏移问题

问题根源

  1. 欧拉角循环导致瞬移:当前代码直接累加yRotation并与固定范围比较,当YCamLimitWhenSteering > 90时,限制范围会跨0/360度边界(比如设为100时,minY=-10、maxY=190),而yRotation会随鼠标输入不断累加(超过360或低于0),直接数值比较会误判边界,触发错误的重置逻辑导致瞬移。
  2. 硬编码90f引发视角偏移:用固定90f作为基准生成限制范围不够灵活,本质是进入驾驶模式时未以玩家当前实际旋转为中心设置限制,导致正前方视角偏左。

修复方案

修改思路

  • 进入驾驶模式时记录玩家当前y轴旋转作为基准角度,以此为中心生成±YCamLimitWhenSteering的限制范围,替代硬编码的90f。
  • 将角度转换为-180°~180°的标准化范围,规避欧拉角0/360循环问题,再进行边界判断。
  • 用Unity内置的Mathf.DeltaAngle处理角度循环,简化限制逻辑。

修改后的完整代码

using UnityEngine;

public class MouseLook : MonoBehaviour
{
    public float mouseSensitivity = 100f;
    public Transform playerBody;

    float xRotation = 0f;
    float yRotation = 0f;
    // 驾驶模式下的基准旋转角度
    float baseYRotation = 0f;

    private bool isLerping = false;
    private bool isSteeringWheel;

    [SerializeField] public int YCamLimitWhenSteering = 70;

    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
    }

    void Update()
    {
        if (isLerping) return;

        float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
        float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

        // 垂直旋转限制(保留原有逻辑)
        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, -90f, 90f);
        transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);

        if (isSteeringWheel)
        {
            yRotation += mouseX;

            // 计算相对于基准角度的偏移量,自动处理360度循环
            float relativeY = Mathf.DeltaAngle(baseYRotation, baseYRotation + yRotation);
            // 钳制偏移量在设定范围内
            float clampedRelativeY = Mathf.Clamp(relativeY, -YCamLimitWhenSteering, YCamLimitWhenSteering);

            // 计算最终目标旋转角度并应用
            float targetY = baseYRotation + clampedRelativeY;
            playerBody.localRotation = Quaternion.Euler(0f, targetY, 0f);
        }
        else
        {
            playerBody.Rotate(Vector3.up * mouseX);
        }
    }

    public void SetSteering(bool isAtWheel)
    {
        isSteeringWheel = isAtWheel;

        if (isAtWheel)
        {
            // 进入驾驶模式时,记录当前玩家y轴旋转作为基准
            baseYRotation = playerBody.localRotation.eulerAngles.y;
            // 重置相对旋转量
            yRotation = 0f;
        }
    }

    public void SetLerping(bool lerping)
    {
        isLerping = lerping;
    }
}

关键改动说明

  1. 基准角度记录:在SetSteering进入驾驶模式时,记录玩家当前eulerAngles.y作为baseYRotation,确保限制范围以当前视角为中心,彻底解决正前方偏移问题,无需硬加90f。
  2. 相对角度处理:Mathf.DeltaAngle自动处理360度循环,返回-180~180之间的角度差值,避免了角度累加导致的数值溢出或循环判断错误。
  3. 边界钳制逻辑:将相对偏移量钳制在设定范围内后再叠加基准角度,无论YCamLimitWhenSteering设为多大(≤180),相机到达边界后都会停止旋转,不会出现瞬移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:43:12