You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Unity相机沿全局XZ平面移动问题:边缘平移适配旋转视角

解决相机倾斜时沿世界XZ平面平移的问题

你碰到的这个问题其实很典型——当相机存在倾斜(Tilt)时,用自身局部坐标系的Vector3.forward/Vector3.back做平移,方向会带上垂直分量,导致相机不是沿水平方向前后移动,而是出现靠近或远离目标物体的偏差。咱们需要改用世界XZ平面上的水平方向来实现平移,同时兼容相机的轨道旋转需求。

替换代码方案

直接把你注释掉的两行前后平移代码,替换成以下内容即可:

鼠标靠近屏幕上边缘(向前平移)

// 提取相机朝向在世界XZ平面上的水平前方向
Vector3 horizontalForward = Vector3.ProjectOnPlane(transform.forward, Vector3.up).normalized;
transform.Translate(horizontalForward * Time.deltaTime * panSpeed, Space.World);

鼠标靠近屏幕下边缘(向后平移)

Vector3 horizontalForward = Vector3.ProjectOnPlane(transform.forward, Vector3.up).normalized;
transform.Translate(-horizontalForward * Time.deltaTime * panSpeed, Space.World);

优化建议:避免重复计算

为了减少重复代码和计算开销,可以在Update方法开头先计算一次水平前方向,后续直接复用:

void Update()
{
    // 提前计算相机的水平前方向(仅保留XZ平面分量)
    Vector3 horizontalForward = Vector3.ProjectOnPlane(transform.forward, Vector3.up).normalized;

    if (Input.mousePosition.y >= Screen.height - brdThcknss) { 
        transform.Translate(horizontalForward * Time.deltaTime * panSpeed, Space.World); 
    } 
    if (Input.mousePosition.y <= brdThcknss) { 
        transform.Translate(-horizontalForward * Time.deltaTime * panSpeed, Space.World); 
    } 

    // 如果你希望左右平移也跟随相机轨道旋转(而非固定世界右方向),可以把左右代码替换成下面这样
    Vector3 horizontalRight = Vector3.ProjectOnPlane(transform.right, Vector3.up).normalized;
    if (Input.mousePosition.x >= Screen.width - brdThcknss) { 
        transform.Translate(horizontalRight * Time.deltaTime * panSpeed, Space.World); 
    } 
    if (Input.mousePosition.x <= brdThcknss) { 
        transform.Translate(-horizontalRight * Time.deltaTime * panSpeed, Space.World); 
    }
}

原理说明

  • Vector3.ProjectOnPlane(transform.forward, Vector3.up):把相机自身的前方向,投影到以世界向上方向(Vector3.up)为法向量的平面(也就是XZ平面)上,彻底剔除垂直方向的分量,得到纯水平的前方向。
  • normalized:确保方向向量的长度始终为1,避免因为相机倾斜角度不同,导致平移速度出现波动。
  • Space.World参数:明确指定平移在世界坐标系下执行,这样不管相机怎么旋转(倾斜或轨道旋转),平移都会严格限制在XZ平面上,完全匹配你的需求。

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

火山引擎 最新活动