首页 > 代码库 > 几种有限状态机的实现
几种有限状态机的实现
有限状态机,除了可以组织游戏逻辑之外,还可以用于实现简单的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的窗口就写了无数个类,个人感觉得不偿失。
几种有限状态机的实现