首页/ 第 8 章 · 输入系统/ 第 120 课
LESSON 120 · 输入系统

跳跃与重力模拟(角色控制器)

跳跃与重力已实现。下一课学 CharacterController 角色控制器。

⏱ 约 15 分钟📊 难度:入门🗂 第 8 章 · 输入系统📍 第 120 / 300 课
课程进度
120 / 300

🎯本节学习目标

  • 实现地面检测
  • 实现跳跃
  • 处理下落与防止连跳

🚀课程导读

“跳起来、落回地面”看似简单,但地面检测、防连跳有无数坑。本课给出可靠方案。

地面检测

判断“脚是否在地面上”。

  1. 【方式1 射线检测】从角色脚下向下发一条短射线:
  2. public float groundCheckDistance = 0.2f;
  3. bool IsGrounded() { return Physics.Raycast(transform.position, Vector3.down, groundCheckDistance); }
  4. 【方式2 球形检测】OverlapSphere 更稳(对地面不平):Physics.CheckSphere(footPos, radius, groundMask)。
  5. 【方式3 触发器脚】角色底部放一个触发器子物体,OnTriggerStay 时置 grounded=true(经典方案)。
  6. 【注意】射线起点应放在“脚底”,距离略大于接触范围。
  7. 【LayerMask】只检测地面层(第 99 课),避免把敌人当地面。
  8. 【踩多个地面】检测结果每帧更新,落地的瞬间 grounded 变 true。
💡
地面检测是跳跃的“开关”:只有 grounded 为 true 时才允许起跳,防无限跳。

跳跃与重力实现

用刚体实现。

  1. 给角色加 Rigidbody(Use Gravity 开)、地面有碰撞体。
  2. 新建脚本 JumpController 挂角色:
  3. public float jumpForce = 8f; public float groundDistance = 0.15f;
  4. Rigidbody rb;
  5. void Awake() { rb = GetComponent<Rigidbody>(); }
  6. void Update() {
  7. bool grounded = Physics.Raycast(transform.position, Vector3.down, groundDistance);
  8. if (Input.GetKeyDown(KeyCode.Space) && grounded) {
  9. rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z); // 先清空垂直速度
  10. rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
  11. }
  12. }
  13. 【说明】跳跃前把 y 速度清零,防止“上抛+残留速度”叠加导致跳太高。
  14. 【重力】刚体 Use Gravity 自动处理下落。
  15. 【可调跳高】跳跃力根据手感调(8 左右较合理)。
  16. 【二段跳】(进阶)设 jumpsRemaining 计数,落地重置。
  17. 【Buffer/Coyote】(进阶)跳跃缓冲与土狼时间提升手感。
可靠跳跃 = 地面检测(射线/球)+ 清空 y 速度 + Impulse 冲量。

常见错误与排查

错误:跳不起来或跳太低?
原因:jumpForce 太小、地面检测距离不对、或 y 速度没清零
解决:调大 jumpForce;检查射线是否检测到地面;跳跃前清空 rb.velocity.y。

动手练习

课后小任务(做出来才算真的学会)

  • 实现带地面检测的跳跃
  • 加入防无限跳逻辑
  • (进阶)实现二段跳

本节小结

跳跃与重力已实现。下一课学 CharacterController 角色控制器。

完成打卡后,主站会实时更新你的学习进度 🎯

← 上一课第三人称跟随相机