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

Unity 3D:如何让玩家对象沿自身坐标系轴移动?

解决玩家沿自身坐标系移动的问题

你的核心问题是当前移动逻辑使用全局坐标系计算位移,导致玩家转向后仍按世界轴移动。要实现沿自身坐标系移动,需基于玩家自身的前向/右向向量计算位移,同时结合物理系统保证移动稳定性。

关键修改思路

  1. 替换全局向量为玩家自身的transform.forward(前向)和transform.right(右向),这两个向量会随玩家旋转自动更新。
  2. 忽略Y轴分量,避免相机上下旋转时玩家产生垂直位移。
  3. 使用Rigidbody.MovePosition替代直接修改transform.position,保证物理交互(比如碰撞、重力)正常工作。
  4. 清理冗余代码,统一命名规范,提升可读性。

修改后的完整代码

PlayerMovement 脚本

using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    public Rigidbody rb;
    public float playerSpeed = 5f; // 给默认移动速度,方便调试

    private float _moveHorizontal;
    private float _moveVertical;

    // 仅在Update中获取输入,保证输入响应及时
    void Update()
    {
        _moveHorizontal = Input.GetAxis("Horizontal");
        _moveVertical = Input.GetAxis("Vertical");
    }

    // 物理相关操作放在FixedUpdate,与物理引擎同步
    void FixedUpdate()
    {
        // 获取玩家水平前向向量(忽略Y轴,避免上下移动)
        Vector3 forward = transform.forward;
        forward.y = 0;
        forward.Normalize();

        // 获取玩家水平右向向量
        Vector3 right = transform.right;
        right.y = 0;
        right.Normalize();

        // 计算最终移动方向,归一化避免斜向移动速度过快
        Vector3 moveDirection = (forward * _moveVertical + right * _moveHorizontal).normalized;

        // 应用位移
        rb.MovePosition(rb.position + moveDirection * playerSpeed * Time.fixedDeltaTime);
    }
}

CameraController 脚本

using UnityEngine;

public class CameraController : MonoBehaviour
{
    public GameObject cameraFocusObject; // 绑定玩家对象,实现玩家随相机转向
    public int sensX = 100;
    public int sensY = 100;

    private float _xRot;
    private float _yRot;

    void Start()
    {
        Cursor.visible = false;
        Cursor.lockState = CursorLockMode.Locked;
    }

    void Update()
    {
        float mouseX = Input.GetAxisRaw("Mouse X") * Time.deltaTime * sensX;
        float mouseY = Input.GetAxisRaw("Mouse Y") * Time.deltaTime * sensY;

        _yRot += mouseX;
        _xRot -= mouseY;
        _xRot = Mathf.Clamp(_xRot, -85f, 85f); // 限制上下旋转角度,避免抬头过度

        // 相机自身旋转(控制上下视角)
        transform.rotation = Quaternion.Euler(_xRot, _yRot, 0);
        // 玩家仅跟随Y轴旋转(控制左右转向)
        cameraFocusObject.transform.rotation = Quaternion.Euler(0, _yRot, 0);
    }
}

配置说明

  1. Player对象设置:
    • 给玩家对象添加Rigidbody组件,勾选Constraints中的Freeze Rotation X和Freeze Rotation Z,防止玩家移动时倾斜。
    • 将PlayerMovement脚本挂在玩家对象上,拖入Rigidbody引用。
  2. 相机设置:
    • 将CameraController脚本挂在主相机上。
    • 在Inspector中把cameraFocusObject设为玩家对象。
  3. 调试建议:
    • 在Scene视图中测试,观察玩家旋转后,WASD是否对应玩家自身的前后左右。
    • 调整playerSpeed和sensX/sensY数值,适配手感。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:22:02