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

Unity实现类场景编辑器轨道相机 如何避免绕自身相对Z轴旋转

问题原因
  • 原代码每帧将X、Y轴旋转相乘后累积应用到正交向量和相机变换上,斜向拖动时两个旋转的叠加会逐步引入绕相机Z轴的滚转误差,累积到一定程度就会出现万向锁死问题。
  • 不需要累积变换到共用的正交向量,改用独立的角度变量控制旋转就能从根源避免滚转误差,同时保留倒置旋转的能力。
修改后完整代码
using UnityEngine;

public class MainCamera : MonoBehaviour
{
    Vector2 mousePosition;
    float pitch = 0f; // 俯仰角
    float yaw = 0f; // 偏航角
    float degreesPerUnitWidth = 180f / Screen.width;
    float degreesPerUnitHeight = 180f / Screen.height;
    float cameraRadius = 10;

    void Start()
    {
        // 初始化角度和初始位置
        transform.position = new Vector3(0, 0, -cameraRadius);
        transform.LookAt(Vector3.zero);
        pitch = transform.eulerAngles.x;
        yaw = transform.eulerAngles.y;
    }

    void LateUpdate()
    {
        if (Input.GetMouseButtonDown(0))
        {
            mousePosition = Input.mousePosition;
        }

        if (Input.GetMouseButton(0))
        {
            Vector2 input = Input.mousePosition;
            Vector2 mouseDelta = mousePosition - input;
            
            // 单独累积两个维度的角度,避免旋转叠加误差
            yaw -= mouseDelta.x * degreesPerUnitWidth;
            pitch -= mouseDelta.y * degreesPerUnitHeight;

            // 直接计算最终旋转位置,不会累积误差
            Quaternion rotation = Quaternion.Euler(pitch, yaw, 0f);
            transform.position = rotation * new Vector3(0, 0, -cameraRadius);
            transform.LookAt(Vector3.zero);
            
            mousePosition = Input.mousePosition;
        }
    }
}
效果说明
  • 完全复刻Unity场景编辑器的轨道相机行为,单独拖动、斜向拖动都不会出现Z轴滚转,也不会触发万向锁。
  • 支持360度全方向旋转和倒置效果,不需要强制锁定世界向上轴。
  • 所有变换默认围绕原点计算,可根据需求将原点替换为自定义的目标锚点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:57:03