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

已启用Rigidbody约束,玩家仍沿X、Z轴随机旋转问题求助

第一人称视角鼠标控制旋转异常问题求助

我使用以下C#代码实现Unity第一人称视角的鼠标控制:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

class FirstPersonCamera : MonoBehaviour
{
    public float mouseSensitivity = 100f;

    public Transform playerTransform;
    public Transform weaponTransform;

    private float xRotation = 0;

    void Start()
    {
        UnityEngine.Cursor.lockState = CursorLockMode.Locked; //隐藏光标并锁定在屏幕中心
    }

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

        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, -90, 90);

        transform.localRotation = Quaternion.Euler(xRotation, 0, 0);
        weaponTransform.localRotation = Quaternion.Euler(xRotation, 0, 0);

        playerTransform.Rotate(new Vector3(0.0f, mouseX, 0.0f));

        // playerTransform.gameObject.GetComponent<Rigidbody>().MoveRotation(Quaternion.Euler(0.0f,mouseX,0.0f));

        if (Input.GetKeyDown(KeyCode.Escape))
        {
            UnityEngine.Cursor.lockState = CursorLockMode.None;
        }
    }
}

问题情况

即使已经锁定了玩家对象Rigidbody组件的X、Z轴旋转,在同时使用键盘移动和鼠标控制视角时,玩家仍会随机沿X、Z轴旋转:
玩家旋转异常

玩家移动代码未处理旋转逻辑,但移除playerTransform.Rotate语句后,旋转异常问题消失。尝试改用Rigidbody的MoveRotation方法实现旋转,却没有任何效果,求解决方法。


解决方案

1. 修正Rigidbody.MoveRotation的使用方式

原来的MoveRotation写法错误,只传入了单帧的mouseX增量,而非累积的Y轴旋转值。正确做法是基于玩家当前的Y轴旋转角度叠加增量:

// 替换原代码中的playerTransform.Rotate语句
Rigidbody playerRb = playerTransform.GetComponent<Rigidbody>();
if (playerRb != null)
{
    // 获取当前玩家Y轴旋转角度
    float currentYRot = playerTransform.eulerAngles.y;
    // 计算新的Y轴旋转角度
    float newYRot = currentYRot + mouseX;
    // 保持X、Z轴为锁定的0值,仅更新Y轴旋转
    playerRb.MoveRotation(Quaternion.Euler(0f, newYRot, 0f));
}

2. 确认Rigidbody约束设置

检查玩家对象的Rigidbody组件:

  • 确保Freeze Rotation下的X、Z选项已勾选,阻止物理引擎修改这两个轴的旋转
  • 排查是否有其他代码动态修改了Rigidbody的Constraints参数

3. 同步物理帧更新

Rigidbody相关操作应放在FixedUpdate中执行,确保与物理引擎帧同步,避免输入与物理更新不同步导致的异常:

private float mouseXDelta = 0f;

void Update()
{
    // 处理鼠标Y轴旋转、光标锁定等逻辑
    float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
    mouseXDelta += mouseX;
}

void FixedUpdate()
{
    if (mouseXDelta != 0f)
    {
        Rigidbody playerRb = playerTransform.GetComponent<Rigidbody>();
        if (playerRb != null)
        {
            float currentYRot = playerTransform.eulerAngles.y;
            float newYRot = currentYRot + mouseXDelta;
            playerRb.MoveRotation(Quaternion.Euler(0f, newYRot, 0f));
        }
        mouseXDelta = 0f;
    }
}

4. 排查移动代码的潜在影响

虽然移动代码声明未处理旋转,但仍需检查:

  • 是否使用Transform.Translate时误操作了旋转
  • 是否在移动逻辑中修改了Rigidbody的角速度或旋转相关属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 09:30:57