如何为WASD控制的移动小球实现惯性效果,使其松键后继续滚动一段距离
实现惯性移动效果方案
核心思路
你当前的逻辑仅在有按键输入时才执行移动计算,松开按键后direction为0就直接停止了移动。要实现惯性效果,需要额外维护一个速度变量记录当前的移动动量:有输入时通过加速度逐步提升速度到目标值,松开按键后通过阻尼逐步衰减速度,全程用这个速度变量驱动移动即可。
新增变量说明
你需要在原有代码基础上新增3个变量:
acceleration:控制有输入时的提速快慢,值越大按键响应越跟手drag:控制无输入时的减速快慢,值越小惯性滑行距离越远currentVelocity:私有变量,用于存储当前的移动动量
完整修改后代码
public float speed = 6f; public float turnSmoothTime = 0.1f; float turnSmoothVelocity; // 新增惯性相关参数 public float acceleration = 8f; public float drag = 3f; private Vector3 currentVelocity; // 代码中缺少的cam和controller声明记得自行补上 // public Camera cam; // public CharacterController controller; // Update is called once per frame void Update() { float horizontal = Input.GetAxisRaw("Horizontal"); float vertical = Input.GetAxisRaw("Vertical"); Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized; if(direction.magnitude >= 0.1f) { // 原有转向逻辑保留 float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y; float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime); transform.rotation = Quaternion.Euler(0f, angle, 0f); Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward; // 有输入时,把当前速度向目标速度平滑过渡 Vector3 targetVelocity = moveDir.normalized * speed; currentVelocity = Vector3.Lerp(currentVelocity, targetVelocity, acceleration * Time.deltaTime); } else { // 无输入时,用阻尼衰减速度 currentVelocity = Vector3.Lerp(currentVelocity, Vector3.zero, drag * Time.deltaTime); } // 不管有没有输入,都用当前速度驱动移动 controller.Move(currentVelocity * Time.deltaTime); }
参数调整建议
- 想要滑行距离更长,把
drag调到2以下即可 - 觉得按键后提速太慢不够跟手,把
acceleration调到10以上 - 如果要做物理滚动的小球效果,可以同时给小球加刚体旋转跟随逻辑,视觉上会更真实
内容的提问来源于stack exchange,提问作者Valentijn Schoen
相关产品推荐
相关产品推荐

