C# Unity基于旋转朝向的物理驱动移动功能实现问题求助
问题根因
你当前的代码核心错误是同时混用了CharacterController和Rigidbody两套物理移动组件,且直接修改transform.position实现移动,绕开了Unity的物理碰撞检测,才会出现穿墙、无法上坡、跳跃异常的问题。CharacterController原生支持上坡、台阶、墙体碰撞检测,非常适合实现第一/第三人称角色移动,不需要额外搭配刚体,下面是修复后的完整实现:
修复后的代码
using UnityEngine; public class pm : MonoBehaviour { private CharacterController characterController; // 移动参数可在Inspector面板调整 public float movementSpeed = 5f; public float runMultiplier = 2.5f; public float jumpHeight = 8f; public float gravity = 20f; private Vector3 moveDir = Vector3.zero; void Start() { characterController = GetComponent<CharacterController>(); // 锁定光标到窗口中心,适配视角转动 Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; } void Update() { // 用CharacterController自带的落地检测,比自己写的碰撞检测更精准 if (characterController.isGrounded) { // 获取 WASD 输入 float horizontalInput = Input.GetAxis("Horizontal"); float verticalInput = Input.GetAxis("Vertical"); moveDir = new Vector3(horizontalInput, 0f, verticalInput); // 将输入方向转换为角色自身朝向的坐标系,实现沿视角方向移动 moveDir = transform.TransformDirection(moveDir); // 处理奔跑逻辑 float currentSpeed = movementSpeed; if (Input.GetKey(KeyCode.LeftShift) && verticalInput > 0) { currentSpeed *= runMultiplier; } moveDir *= currentSpeed; // 处理跳跃 if (Input.GetKeyDown(KeyCode.Space)) { moveDir.y = jumpHeight; } } // 每帧施加重力 moveDir.y -= gravity * Time.deltaTime; // 调用CharacterController的Move方法移动,自动处理碰撞、上坡、台阶 characterController.Move(moveDir * Time.deltaTime); } }
配置注意事项
- 删除角色身上的
Rigidbody组件,CharacterController不需要搭配刚体使用,二者共存会导致逻辑冲突 - 调整
CharacterController组件参数:Slope Limit:设置可攀爬的最大坡度,默认45度可满足多数需求Step Offset:设置可攀爬的最大台阶高度,建议设为0.2~0.4Skin Width:建议设为0.08,避免卡墙
- 视角旋转逻辑只需要旋转胶囊体的Y轴(水平方向转动),上下俯仰的旋转单独挂在子节点的相机上,即可保证移动方向和视角朝向一致
内容的提问来源于stack exchange,提问作者BEANStime
相关产品推荐
相关产品推荐

