Unity 玩家状态机学习记录:Idle、Move、Jump、Fall 和墙面状态

最近在 Unity 2D 项目里,我把玩家的移动逻辑整理成了状态机。这样做的目的,是把不同动作下的逻辑分开管理,避免所有判断都堆在 Player 的 Update 里。

我的实现里有一个 StateMachine,里面保存当前状态 currentState。开始时用 Initialize 进入初始状态,切换状态时通过 ChangeState 先退出旧状态,再进入新状态,最后每一帧只更新当前状态。每个状态都继承自 EntityState,进入状态时打开对应的 Animator Bool,退出状态时关闭它,同时每帧把 yVelocity 传给动画控制器,用来区分跳跃和下落表现。

目前我实现的玩家状态主要有六个:Idle、Move、Jump、Fall、WallSlide 和 WallJump。

Idle 是待机状态。玩家没有水平输入时进入这个状态,进入时会把水平速度清零。如果检测到移动输入,就切换到 Move;如果按下跳跃键,则通过地面状态的公共逻辑切换到 Jump。

Move 是移动状态。这个状态根据 moveInput.x 和 moveSpeed 设置玩家水平速度,同时会处理角色朝向翻转。如果移动输入变成 0,就回到 Idle。如果玩家离开地面或按下跳跃键,也会切到对应的 Fall 或 Jump。

Jump 是跳跃状态。进入这个状态时,会给 Rigidbody2D 一个向上的 jumpForce,让角色起跳。跳跃过程中仍然继承空中状态的逻辑,可以进行一定程度的空中水平控制。当 y 方向速度小于 0 时,说明角色开始下落,就切换到 Fall。

Fall 是下落状态。它负责处理角色在空中的下落过程,同时也会继续允许空中移动。如果检测到墙面并且没有接触地面,就切换到 WallSlide;如果重新检测到地面,就回到 Idle。

WallSlide 是贴墙下滑状态。当角色在空中碰到墙时进入这个状态。这里会根据 wallSlideSpeed 降低下落速度,让角色不是直接掉下去。如果按下跳跃键,就切换到 WallJump;如果离开墙面,就进入 Fall;如果落地,就回到 Idle。

WallJump 是墙跳状态。进入时会根据当前朝向的反方向和 wallJumpForce 给角色一个速度,让角色从墙上弹开。如果之后 y 速度开始变小,就进入 Fall;如果又检测到墙面,则可以重新切回 WallSlide。

这套状态机的好处是,每个状态只负责自己该做的事情。比如 Idle 只关心站立和进入移动,Jump 只关心起跳和转下落,WallSlide 只关心贴墙下滑和墙跳。Player 本身只负责创建状态、检测碰撞、更新当前状态,整体结构会比把所有 if 判断都写在一个 Update 里清楚很多。

posted @ 2026-05-09 14:21  GhbBskl  阅读(35)  评论(0)    收藏  举报