Unity必备:状态机FSM

状态机FSM

前往个人博客,享受无广告阅读,获取更好体验

前言

状态机是很奇妙的东西,在做简单的小项目几乎用不上它。但一旦项目复杂想做的功能多了,就必须使用规范的状态机。不然各个状态切换会极其困难。
与其在一个类数百行代码管理数个状态,不如一个状态一个类,这样今后添加修改会方便的多。
我学习了一种常见的状态机写法:

  • 每一个状态具有一个独立的state类,其规定这个状态特有的行为;
  • 有一个或多个statemachine类管理state的切换;

它遵循“状态模式”以及“策略模式”,符合单一职责原则与接口隔离原则。

内容

1. 定义状态接口

首先,定义一个状态接口,每个状态都需要实现这个接口。

public interface IState
{
    void Enter();
    void Execute();
    void Exit();
}
  • Enter():当进入这个状态时执行的逻辑。
  • Execute():在这个状态下每一帧执行的逻辑。
  • Exit():当离开这个状态时执行的逻辑。

2. 实现具体的状态

接下来,实现具体的状态类,举例如下:

public class IdleState : IState
{
    public void Enter()
    {
        Debug.Log("Entering Idle State"); 
        animator.Play("Idle"); // 播放Idle动画;
    }

    public void Execute()
    {
        Debug.Log("Executing Idle State");
        //例如输入不为0,则进入特定状态;
    }

    public void Exit()
    {
        Debug.Log("Exiting Idle State");
    }
}

public class MoveState : IState
{
    public void Enter()
    {
        Debug.Log("Entering Move State");
        animator.Play("Move"); // 播放移动动画
        //监听其他行为,例如按下`shift`,那么切换到跑步状态。
    }

    public void Execute()
    {
	    Move();
	    //进入移动动画
        Debug.Log("Executing Move State");
    }

    public void Exit()
    {
        Debug.Log("Exiting Move State");
        //取消特定的监听。
    }

	private void Move()
	{
		//实现移动
	}
}

事实上,我通常会添加一个movement状态,关于移动的细分状态继承于它,毕竟移动状态会有大量的相同逻辑,例如将移动输入映射到动画控制器。

3. 创建状态机管理器

然后,创建一个状态机管理器,用于切换状态和执行当前状态的逻辑。

public class StateMachine
{
    private IState currentState;
	// 提供状态切换的接口;
    public void ChangeState(IState newState)
    {
        if (currentState != null)
        {
            currentState.Exit();
        }

        currentState = newState;
        currentState.Enter();
    }

    public void Update()
    {
        if (currentState != null)
        {
            currentState.Execute();
        }
    }
}

4. 在Unity中使用

在你的游戏对象中使用这个状态机。你可以在Update方法中调用状态机的Update方法,以执行当前状态的逻辑。

public class PlayerController : MonoBehaviour
{
    private StateMachine stateMachine;

    void Start()
    {
        stateMachine = new StateMachine();
        stateMachine.ChangeState(new IdleState()); // 初始状态为Idle
    }

    void Update()
    {
        stateMachine.Update();
    }
}

5. 优点及缺点

  • 可扩展性:添加新的状态非常方便,不会影响现有的状态逻辑。
  • 可维护性:状态之间是解耦的,代码容易调试和维护。
  • 模块化:状态的职责是独立的,代码结构更加清晰。

  • 文件数量多:每个状态都有一个单独的类,会导致项目中文件数量增多,结构变得复杂。
  • 初期架构复杂:状态机的初期搭建比较困难。
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云璃丶夢紡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值