Unity 2D 玩家控制器学习记录
一、脚本概述
这是一个基于 Rigidbody2D 的 2D 玩家控制器,实现了水平移动、跳跃、攻击、翻转、地面检测和动画同步等基础功能,适合用于横版 2D 游戏(如平台跳跃或割草类游戏)。
依赖组件:
-
Rigidbody2D:物理移动 -
Animator(子物体上):动画控制
二、字段说明
移动参数
| 字段 | 类型 | 作用 |
|---|---|---|
xMove |
float | 水平输入值 |
moveSpeed |
float | 水平移动速度,默认 5 |
jumpForce |
float | 跳跃力,默认 5 |
canJump |
bool | 是否允许跳跃(当前未使用) |
isRight |
bool | 是否面朝右 |
碰撞参数
| 字段 | 类型 | 作用 |
|---|---|---|
GroundLayer |
LayerMask | 地面图层 |
GroundCheckDistance |
float | 地面检测射线长度,默认 1.35 |
isGrounded |
bool | 是否在地面 |
攻击参数
| 字段 | 类型 | 作用 |
|---|---|---|
isAttack |
bool | 攻击状态标记(当前未使用) |
三、生命周期
Awake() → 获取 Rigidbody2D 和 Animator
Start() → 空
Update() → 每帧执行:碰撞检测 → 输入 → 移动 → 翻转 → 动画
⚠️ 注意:物理相关操作(
rb.velocity)放在Update中虽然能运行,但更规范的做法是放在FixedUpdate中,避免帧率波动导致移动不一致。
四、核心功能解析
1. 输入处理 HandleInput
xMove = Input.GetAxis("Horizontal");
if (Input.GetKeyDown(KeyCode.Space)) TryToJump();
if (Input.GetKeyDown(KeyCode.Mouse0)) TryToAttack();
-
Input.GetAxis("Horizontal")获取水平输入(带平滑过渡,范围 -1 ~ 1) - 空格键 → 尝试跳跃
- 鼠标左键 → 尝试攻击
2. 移动 HandleMove
rb.velocity = new Vector2(xMove * moveSpeed, rb.velocity.y);
- 保留 y 轴速度,只修改 x 轴,避免影响跳跃/重力
3. 跳跃 TryToJump
if (isGrounded)
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
- 只有在地面时才可跳跃
- 直接设置 y 速度,简单直接
4. 攻击 TryToAttack
if (isGrounded)
anim.SetTrigger("isAttack");
- 仅在地面可攻击
- 通过 Animator 触发器播放攻击动画(实际伤害判定通常在动画事件中处理)
5. 地面检测 HandleCollision
isGrounded = Physics2D.Raycast(transform.position, Vector2.down, GroundCheckDistance, GroundLayer);
- 从玩家位置向下发射射线
- 命中
GroundLayer图层则判定为在地面 -
GroundCheckDistance决定射线长度(默认 1.35)
6. 翻转 HandleFlip / flip
void flip()
{
transform.Rotate(0f, 180f, 0f);
isRight = !isRight;
}
- 根据 x 速度方向判断是否需要翻转
- 使用
Rotate绕 y 轴旋转 180° 实现朝向切换
⚠️ 注意:用
Rotate翻转会同时旋转所有子物体(包括碰撞体、攻击判定点)。更常见的做法是修改localScale.x的符号,或只翻转 Sprite 子物体。
7. 动画同步 HandleAnimation
anim.SetFloat("xVelocity", xMove);
anim.SetFloat("yVelocity", rb.velocity.y);
anim.SetBool("isGrounded", isGrounded);
- 将水平输入、垂直速度、是否在地面传给 Animator
- 动画状态机根据这些参数切换 idle / run / jump / fall 等状态
五、代码中可改进的点
| 问题 | 建议 |
|---|---|
物理操作在 Update
|
移至 FixedUpdate
|
Rotate 翻转影响子物体 |
改用 localScale.x *= -1 或只翻转 Sprite |
canJump 声明未使用 |
补全逻辑或删除 |
isAttack 声明未使用 |
补全逻辑或删除 |
| 攻击无冷却/无判定 | 加入攻击 CD 和伤害检测 |
| 地面检测只有一条射线 | 可用 OverlapCircle 或左右两条射线更稳定 |
Start() 为空 |
可删除或补充初始化逻辑 |
| 未做输入锁定 | 可加入 canMove 等开关控制状态 |
六、知识点总结
-
Rigidbody2D.velocity:直接控制速度,比
AddForce更适合精准的平台跳跃手感。 - Physics2D.Raycast:射线检测,常用于地面检测、墙壁检测、视线检测。
- LayerMask:图层过滤,避免射线检测到玩家自身或无关物体。
- Animator SetTrigger / SetFloat / SetBool:动画状态机参数控制。
-
Input.GetAxis vs GetAxisRaw:
GetAxis带平滑,GetAxisRaw直接返回 -1/0/1。 - 翻转朝向:通过判断速度方向切换角色朝向,是 2D 角色控制的基础。
七、后续扩展方向
- 加入 攻击判定(OverlapCircle + 敌人图层)
- 加入 受伤/无敌帧 逻辑
- 加入 土狼时间(Coyote Time) 和 跳跃缓冲
- 加入 二段跳
- 加入 输入锁定(受击/剧情时禁用移动)
- 与割草类怪物系统结合:怪物不互相碰撞,玩家攻击用空间分区检测
记录时间:学习 Unity 2D 角色控制阶段
关键词:Rigidbody2D、射线检测、动画状态机、输入锁定