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

Unity 3D空间中立方体横竖轴旋转异常问题求助

Unity 立方体旋转异常问题解决

问题描述

我希望在Unity中实现立方体沿垂直轴(左右)和水平轴(上下)的旋转,设置了左右、上下4个输入,每个轴的输入范围为-180至180度。目前尝试了以下代码:

Vector3 targetEulerAngles = new Vector3(y, 0, 0); // Target rotation in Euler angles
m_transForYaw.eulerAngles = (targetEulerAngles);

targetEulerAngles = new Vector3(0, 0, -x);

m_tranfForPitch.eulerAngles= (targetEulerAngles);

m_transRotateAround.rotation = m_transForYaw.rotation * m_tranfForPitch.rotation;

遇到的问题是:当X轴旋转角度超过90度时,m_transForYaw不再向侧面旋转,而是绕forward轴旋转。我也尝试过使用RotateAround方法,但问题依旧。

经排查问题源于前置旋转顺序:

  1. 先绕Vector.right旋转,立方体前后转动,行为正常;
  2. 再绕Vector.up旋转,立方体不再左右转动,而是绕全局Vector.forward轴旋转。

解决方案

这个问题本质是欧拉角万向锁导致的,同时当前旋转组合逻辑没有正确区分局部轴与全局轴的旋转优先级。以下是两种实用的解决思路:

方法1:用四元数维护独立旋转角度

单独维护上下(Pitch)和左右(Yaw)的旋转角度,通过四元数组合旋转,避免欧拉角的万向锁问题:

// 声明变量存储旋转角度,范围限制在-180~180度
float pitchAngle = 0f;
float yawAngle = 0f;
public float rotationSpeed = 2f; // 旋转速度控制

void Update()
{
    // 根据输入更新角度(假设xInput是上下输入,yInput是左右输入)
    pitchAngle = Mathf.Clamp(pitchAngle + xInput * rotationSpeed, -180f, 180f);
    yawAngle = Mathf.Clamp(yawAngle + yInput * rotationSpeed, -180f, 180f);

    // 先构建左右旋转(绕Y轴),再叠加上下旋转(绕X轴)
    // 四元数乘法顺序:先应用yaw,再基于yaw后的空间应用pitch
    Quaternion yawRot = Quaternion.Euler(0, yawAngle, 0);
    Quaternion pitchRot = Quaternion.Euler(pitchAngle, 0, 0);
    transform.rotation = yawRot * pitchRot;
}

方法2:父子层级分离旋转轴

通过创建父子空物体,分离上下和左右的旋转逻辑,彻底规避万向锁:

  1. 创建父物体YawRoot:负责左右旋转(绕全局Up轴)
  2. 创建子物体PitchRoot(作为YawRoot的子物体):负责上下旋转(绕自身Right轴)
  3. 将立方体作为PitchRoot的子物体

代码控制如下:

public Transform yawRoot;
public Transform pitchRoot;
public float rotationSpeed = 2f;

void Update()
{
    // 左右旋转:父物体绕全局Up轴旋转
    yawRoot.Rotate(Vector3.up, yInput * rotationSpeed, Space.World);
    // 上下旋转:子物体绕自身Right轴旋转
    pitchRoot.Rotate(Vector3.right, xInput * rotationSpeed, Space.Self);

    // 限制旋转范围在-180~180度
    // 处理欧拉角0-360到-180-180的转换
    Vector3 pitchLocalEuler = pitchRoot.localEulerAngles;
    pitchLocalEuler.x = Mathf.Repeat(pitchLocalEuler.x + 180f, 360f) - 180f;
    pitchLocalEuler.x = Mathf.Clamp(pitchLocalEuler.x, -180f, 180f);
    pitchRoot.localEulerAngles = pitchLocalEuler;

    Vector3 yawLocalEuler = yawRoot.localEulerAngles;
    yawLocalEuler.y = Mathf.Repeat(yawLocalEuler.y + 180f, 360f) - 180f;
    yawLocalEuler.y = Mathf.Clamp(yawLocalEuler.y, -180f, 180f);
    yawRoot.localEulerAngles = yawLocalEuler;
}

核心原因说明

  • 欧拉角万向锁:当X轴旋转至90度时,Y轴和Z轴的旋转轴会重合,导致旋转方向异常,四元数或层级分离的方式可以避免这个问题。
  • 局部轴优先级:左右旋转应该基于物体当前朝向的局部Up轴,而非全局Up轴,否则旋转到一定角度后会出现方向偏移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:21:05