添加Character Controller后角色移动时上浮0.08单位的问题
问题:添加Character Controller后角色启动移动时上浮0.08单位
为角色添加Character Controller组件后,仅在开始移动时会向上浮起0.08单位,碰撞器位置显示正常。
相关截图
- 带有Character Controller组件的角色:

- 角色设置面板:

角色移动代码
[SerializeField] private Transform _orientation; private CharacterController _controller; private float xInput; private float yInput; private Vector3 _moveDirection; private float rotationSpeed = 10f; private float speed = 5f; private void Awake() { _controller = GetComponent<CharacterController>(); } private void Start() { Cursor.lockState = CursorLockMode.Locked; } private void Update() { xInput = Input.GetAxis("Horizontal"); yInput = Input.GetAxis("Vertical"); _moveDirection = _orientation.forward * yInput + _orientation.right * xInput; RotatePlayerToCameraView(); Move(_moveDirection); } private void RotatePlayerToCameraView() { Vector3 viewDirection = transform.position - new Vector3(_orientation.position.x, transform.position.y, _orientation.position.z); _orientation.forward = viewDirection.normalized; // 待理解此行作用 gameObject.transform.forward = Vector3.Slerp(gameObject.transform.forward, viewDirection.normalized, Time.deltaTime * rotationSpeed); } private void Move(Vector3 moveDirection) { float scaledMoveSpeed = speed * Time.deltaTime; moveDirection = new Vector3(moveDirection.x, 0, moveDirection.z); _controller.Move(moveDirection * scaledMoveSpeed); }
问题排查与解决方法
1. 调整Character Controller的Skin Width参数
Character Controller默认的Skin Width为0.08,这刚好和你遇到的上浮数值匹配。该参数用于碰撞检测的缓冲,值过大时,首次移动可能触发角色位置校正导致上浮。
- 在Inspector面板中找到Character Controller组件,将Skin Width调至0.04左右(不要设为0,否则会丢失碰撞缓冲),测试是否解决问题。
2. 添加重力模拟,确保角色贴合地面
当前代码完全忽略了重力,Character Controller不会自动处理重力,导致角色无法稳定贴合地面,移动时易出现位置偏移。修改Move方法,加入重力逻辑:
private float gravity = -9.81f; private Vector3 _velocity; private void Move(Vector3 moveDirection) { float scaledMoveSpeed = speed * Time.deltaTime; // 地面贴合处理:角色在地面时重置重力速度,轻微下压避免浮空 if (_controller.isGrounded && _velocity.y < 0) { _velocity.y = -2f; } _velocity.y += gravity * Time.deltaTime; // 确保移动方向为单位向量,避免斜向移动速度过快 moveDirection = new Vector3(moveDirection.x, 0, moveDirection.z).normalized; // 同时应用移动速度和重力 _controller.Move((moveDirection * scaledMoveSpeed) + _velocity * Time.deltaTime); }
添加重力后,角色会持续受到向下的力,始终贴合地面,从根源避免移动时的上浮现象。
3. 检查初始位置是否存在间隙
确认角色Transform的Y轴位置是否让Character Controller底部与地面存在微小间隙。可以手动调整角色Y轴位置,让碰撞器底部刚好接触地面,减少首次移动时的位置校正触发。
内容的提问来源于stack exchange,提问作者laflare247
相关产品推荐
相关产品推荐

