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

Unity 3D FPS相机Y轴旋转无限制问题求助(附控制脚本)

嘿,我来帮你搞定这个相机旋转无限制的问题!你现在的FPS游戏里相机能随便上下翻跟头对吧?这确实很影响体验,刚好可以用Mathf.Clamp来解决,我给你一步步改代码,保证搞定~

首先先给你简单说下Mathf.Clamp的用法:它就是把一个数值死死限制在你设定的最小值和最大值之间,语法是Mathf.Clamp(要限制的值, 最小值, 最大值),刚好适合用来控制相机的上下旋转角度(也就是绕X轴的旋转)。

第一步:修改PlayerMotor脚本

我们需要跟踪相机当前的X轴旋转角度,每次更新时用Mathf.Clamp把它锁在合理范围内(比如-89°到89°,避免完全翻转)。下面是修改后的完整代码:

using UnityEngine;

[RequireComponent(typeof(Rigidbody))]
public class PlayerMotor : MonoBehaviour
{
    [SerializeField] private Camera cam;

    private Vector3 velocity = Vector3.zero;
    private Vector3 rotation = Vector3.zero;
    // 改成存储相机X轴的累积旋转角度,而不是每次的增量
    private float cameraXRotation = 0f;

    private Rigidbody rb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        // 把光标锁定的代码移到Start里,不用每次旋转都执行
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    public void Move(Vector3 _velocity)
    {
        velocity = _velocity;
    }

    public void Rotate(Vector3 _rotation)
    {
        rotation = _rotation;
    }

    public void RotateCamera(Vector3 _cameraRotation)
    {
        // 把输入的旋转增量加到累积角度上
        cameraXRotation += _cameraRotation.x;
        // 用Mathf.Clamp限制角度在-89到89度之间,防止相机翻转
        cameraXRotation = Mathf.Clamp(cameraXRotation, -89f, 89f);
    }

    void FixedUpdate()
    {
        PerformMovement();
        PerformRotation(); // 修正了你原来拼写错误的方法名:Preform → Perform
    }

    void PerformMovement()
    {
        if (velocity != Vector3.zero)
        {
            rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime);
        }
    }

    void PerformRotation()
    {
        rb.MoveRotation(rb.rotation * Quaternion.Euler(rotation));

        if (cam != null)
        {
            // 直接设置相机的局部X轴旋转为我们限制后的角度
            cam.transform.localRotation = Quaternion.Euler(cameraXRotation, 0f, 0f);
        }
    }
}

第二步:优化PlayerController脚本(可选但推荐)

你原来的代码里鼠标旋转没有乘以Time.deltaTime,这会导致不同帧率的设备上旋转速度不一样,所以我顺便给你加上这个优化,同时修正了类名的拼写(PlayerControler → PlayerController,规范一点):

using UnityEngine;

[RequireComponent(typeof(PlayerMotor))]
public class PlayerController : MonoBehaviour
{
    private float speed = 5f;
    float lookSensitivity = 70f;
    private PlayerMotor motor;

    void Start()
    {
        motor = GetComponent<PlayerMotor>();
    }

    void Update()
    {
        float _xMov = Input.GetAxis("Horizontal");
        float _zMov = Input.GetAxis("Vertical");

        Vector3 _movHorizontal = transform.right * _xMov;
        Vector3 _movVertical = transform.forward * _zMov;

        Vector3 _velocity = (_movHorizontal + _movVertical).normalized * speed;
        motor.Move(_velocity);

        // 人物旋转:乘以Time.deltaTime让速度和帧率无关
        float _yRot = Input.GetAxis("Mouse X") * lookSensitivity * Time.deltaTime;
        Vector3 _rotation = new Vector3(0f, _yRot, 0f);
        motor.Rotate(_rotation);

        // 相机旋转:同样乘以Time.deltaTime,保持你原来的反转逻辑
        float _xRot = Input.GetAxis("Mouse Y") * lookSensitivity * Time.deltaTime;
        Vector3 _cameraRotation = new Vector3(_xRot, 0f, 0f);
        motor.RotateCamera(_cameraRotation);
    }
}

关键改动说明:

  • Mathf.Clamp的核心作用:在RotateCamera方法里,我们把相机的X轴旋转累积角度限制在-89°到89°之间,这样相机就不会向后翻超过垂直方向,完全符合FPS游戏的正常视角逻辑。
  • 累积角度跟踪:改用单个float变量存储相机当前的X轴旋转角度,而不是每次的增量,这样才能正确对总角度进行限制,而不是限制单次旋转的增量。
  • 细节优化:修正了拼写错误、把光标锁定代码移到Start方法(避免重复执行)、添加Time.deltaTime保证旋转速度稳定。

这样修改后,你测试一下,相机上下旋转就会被牢牢限制在合理范围内,不会再出现无限翻转的问题啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:49:45