首页 > 代码库 > 几种有限状态机的实现

几种有限状态机的实现

有限状态机,除了可以组织游戏逻辑之外,还可以用于实现简单的AI。实现有限状态机的方法有很多,大多数是跨语言的,也有几种依赖MonoBehaviour的。

 

传统的FSM

https://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867

在这篇文章中,介绍了两种FSM的实现方法。第一种是这样的:

public class FSM {
    private var activeState :Function; // points to the currently active state function
 
    public function FSM() {
    }
 
    public function setState(state :Function) :void {
        activeState = state;
    }
 
    public function update() :void {
        if (activeState != null) {
            activeState();
        }
    }
}

在Unity中可以换个写法,让FSM继承MonoBehaviour,在Update中调用SendMessage("Update" + state, SendMessageOptions.RequireReceiver);

然后在FSM中添加一个成员变量string state = "IDLE";并添加类似void UpdateIDLE(){}的成员函数,通过修改state使FSM自动切换到不同状态。

这种方法相当于暴力地在状态与状态之间切换,但这么做在实现蚂蚁的AI时会出问题,可以看下面这张图:

技术分享

在findLeaf状态如果鼠标碰到了蚂蚁,该切换到runAway状态,按理说在goHome状态如果鼠标碰到了蚂蚁,也该切换到runAway状态,但是一旦添加了这个切换,当鼠标移开之后就没法知道该切换到findLeaf状态还是goHome状态,这种写法并没有记录状态切换的来源,也就是没有为状态之间建立关联。第二种基于栈的FSM则弥补了这种不足。

一个更完整的基于图的FSM在这里(《游戏编程精粹1》第三章第一节):

http://wiki.unity3d.com/index.php/Finite_State_Machine

 

另类的FSM

http://jacksondunstan.com/articles/3137

这个FSM的强大之处在于完美融合了协程而且稍加修改便可成为分层FSM!这个FSM也是我最喜欢的。在Execute中可以任意yield,很容易地实现传统FSM里难做的同步。

http://jacksondunstan.com/articles/3726

这是最近几天更新的,一种更简单的使用协程实现FSM的方法。

 

可视化的FSM

http://unitycoding.com/icode/

ICode是Unity的一个插件,把设计FSM变成了拖拖拽拽。歪果仁好像很喜欢这种可视化方式?类似的插件很多。我看过ICode的源码,为了实现类似Animator的窗口就写了无数个类,个人感觉得不偿失。

几种有限状态机的实现