Unity玩家移动异常问题:未碰撞物体时角色可飞行求助
解决Unity角色无碰撞时“飞行”的问题
嘿,刚看完你的代码,立马就找到问题根源啦!你的角色之所以会没碰撞也能“飞行”,核心原因是没正确实现重力逻辑——不仅把重力相关代码注释了,还没处理CharacterController的垂直方向运动。
CharacterController不会自动帮你处理重力,得咱们手动写逻辑来模拟。下面一步步帮你修复:
问题出在哪?
你代码里这行关键代码被注释掉了:
// movement.y = gravity;
就算不注释,直接这么写也不对——重力是持续的加速度,应该不断累加垂直方向的速度,而不是直接赋值固定值。这就导致角色的y轴一直保持0,不会下落,看起来就像悬浮飞行。
修复步骤
我们需要添加一个变量跟踪垂直速度,再结合CharacterController.isGrounded判断角色是否在地面,这样就能实现正常的下落和地面停留:
- 新增私有变量存储垂直速度:
private float _verticalVelocity;
- 在Update里重写重力逻辑:
- 角色在地面时,重置垂直速度(加个小偏移让角色贴住地面,避免悬空)
- 角色不在地面时,持续累加重力加速度
- 将垂直速度赋值给movement.y
修改后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player_Movement : MonoBehaviour { public float speed = 4.0f; public float gravity = -9.8f; // 落地缓冲值,让角色更贴合地面 public float groundOffset = -0.1f; private CharacterController _charCont; private float _verticalVelocity; void Start() { _charCont = GetComponent<CharacterController>(); } void Update() { // 处理水平移动 float deltaX = Input.GetAxis("Horizontal") * speed; float deltaZ = Input.GetAxis("Vertical") * speed; Vector3 movement = new Vector3(deltaX, 0, deltaZ); movement = Vector3.ClampMagnitude(movement, speed); movement = transform.TransformDirection(movement); // 处理重力与地面检测 if (_charCont.isGrounded) { // 地面上重置垂直速度,加小偏移避免悬空 _verticalVelocity = groundOffset; } else { // 空中持续累加重力 _verticalVelocity += gravity * Time.deltaTime; // 可选:限制最大下落速度,避免速度过快 // _verticalVelocity = Mathf.Max(_verticalVelocity, -20f); } // 应用垂直速度 movement.y = _verticalVelocity; movement *= Time.deltaTime; _charCont.Move(movement); } }
给Unity新手的额外提示
CharacterController.isGrounded需要胶囊体和地面有轻微重叠才会返回true,如果角色还是偶尔悬空,可以调大组件的Skin Width参数(比如0.08)- 重力值可以根据游戏手感调整,设为-15会让下落更快,更有重量感
- 要是想加跳跃功能,只需要在
isGrounded判断里加跳跃输入逻辑,给_verticalVelocity一个向上的速度就行
内容的提问来源于stack exchange,提问作者Daniel Anyż
相关产品推荐
相关产品推荐

