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

Unity相机X轴旋转负数值异常锁定至Clamp最大值问题求助

相机旋转Clamp异常问题排查与解决

问题描述

当cameraPivotPoint的X轴旋转值变为负数时,无论怎么设置Clamp参数,它都会被强制设为Clamp的最大值。即使把最大值设为负数,问题依然存在。

问题代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerCntroller : MonoBehaviour
{
    [Header("GameObjects")]
    [SerializeField] GameObject mainCamera;
    [SerializeField] GameObject cameraPivotPoint;
    
    [Header("Input")]
    [SerializeField] PlayerInput input;
    
    [Header("Vector 3s")]
    [SerializeField] Vector3 cameraOffset;

    [Header("Vector 2s")]
    [SerializeField] Vector2 mouse;

    void Start()
    {
        mainCamera.transform.position = cameraPivotPoint.transform.position + cameraOffset;
    }

    void Update()
    {
        Camera();
    }

    void Camera()
    {
        mouse = input.actions["Look Around"].ReadValue<Vector2>();

        cameraPivotPoint.transform.rotation *= Quaternion.AngleAxis(mouse.y, Vector3.right); // 上下旋转相机
        cameraPivotPoint.transform.rotation *= Quaternion.AngleAxis(mouse.x, Vector3.up); // 左右旋转相机
        cameraPivotPoint.transform.position = this.transform.position;
        cameraPivotPoint.transform.eulerAngles = new Vector3(Mathf.Clamp(cameraPivotPoint.transform.eulerAngles.x, -70f, 70f), cameraPivotPoint.transform.eulerAngles.y, 0);
    }
}

问题原因

Unity中transform.eulerAngles的返回值范围是0°到360°,不存在负数角度。当你尝试设置负数角度时,Unity会自动将其转换为对应的正数角度(比如-70°会被转为290°)。这就导致你调用Mathf.Clamp(eulerAngles.x, -70f, 70f)时,实际传入的x值可能是290°这类大于70°的数,自然会被Clamp到最大值70°。

解决方案

方案1:维护独立的旋转变量(推荐)

不要直接操作transform.eulerAngles,而是维护一个单独的float变量来跟踪X轴旋转角度,处理完Clamp后再赋值给transform:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerCntroller : MonoBehaviour
{
    [Header("GameObjects")]
    [SerializeField] GameObject mainCamera;
    [SerializeField] GameObject cameraPivotPoint;
    
    [Header("Input")]
    [SerializeField] PlayerInput input;
    
    [Header("Vector 3s")]
    [SerializeField] Vector3 cameraOffset;

    [Header("Vector 2s")]
    [SerializeField] Vector2 mouse;

    // 维护独立的X轴旋转角度变量
    private float cameraXRotation = 0f;

    void Start()
    {
        mainCamera.transform.position = cameraPivotPoint.transform.position + cameraOffset;
    }

    void Update()
    {
        Camera();
    }

    void Camera()
    {
        mouse = input.actions["Look Around"].ReadValue<Vector2>();

        // 更新X轴旋转角度
        cameraXRotation += mouse.y;
        // 先Clamp角度范围
        cameraXRotation = Mathf.Clamp(cameraXRotation, -70f, 70f);

        // 应用旋转:X轴用维护的变量,Y轴直接累加
        cameraPivotPoint.transform.rotation = Quaternion.Euler(cameraXRotation, cameraPivotPoint.transform.eulerAngles.y + mouse.x, 0);
        cameraPivotPoint.transform.position = this.transform.position;
    }
}

方案2:转换eulerAngles到正负范围后再Clamp

如果你坚持使用transform.eulerAngles,可以先将X轴角度转换为-180°到180°的范围,再进行Clamp:

void Camera()
{
    mouse = input.actions["Look Around"].ReadValue<Vector2>();

    cameraPivotPoint.transform.rotation *= Quaternion.AngleAxis(mouse.y, Vector3.right);
    cameraPivotPoint.transform.rotation *= Quaternion.AngleAxis(mouse.x, Vector3.up);
    cameraPivotPoint.transform.position = this.transform.position;

    // 将X轴角度转换为-180到180范围
    float xAngle = cameraPivotPoint.transform.eulerAngles.x;
    if (xAngle > 180f)
    {
        xAngle -= 360f;
    }
    // 再进行Clamp
    xAngle = Mathf.Clamp(xAngle, -70f, 70f);
    // 转换回0-360范围赋值
    if (xAngle < 0f)
    {
        xAngle += 360f;
    }
    cameraPivotPoint.transform.eulerAngles = new Vector3(xAngle, cameraPivotPoint.transform.eulerAngles.y, 0);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 15:33:38