有限状态机(FSM)
在游戏开发中,AI是个永恒不变的话题,如果你要的AI只是很简单的一个逻辑
那么有限状态机是一个很好的解决方案,尽管在实际开发中,AI的设计并不是一个简单的逻辑,
如果用有限状态机,维护起来会非常麻烦,但还是有必要记一笔。
为什么说维护起来很麻烦?
画一个图就知道了。
在状态不是很多的时候,要维护的状态就少,实现起来也很简单。
但是,一旦状态一多,要维护的状态就多了,
每增加一个状态,就要维护这个状态到其他各个状态之间的实现
当状态越来越多的时候,你就会觉得心有余而力不足了。
代码1:
using System; using System.Collections; using System.Collections.Generic; namespace ShiHuanJue.FSM { public abstract class FSMParent { #region 公共变量 public string m_currentState = string.Empty; #endregion #region 私有变量 protected Dictionary<string, IState> theFSM = new Dictionary<string, IState>(); #endregion public FSMParent() { } public virtual void ChangeStatus(string newState, params Object[] args) { if (this.m_currentState == newState) { UnityEngine.Debug.Log("oldState = newState"); return; } if (!this.theFSM.ContainsKey(newState)) { UnityEngine.Debug.Log("newState is not in stateList"); return; } if(this.theFSM.ContainsKey(this.m_currentState)) this.theFSM[this.m_currentState].Exit(args); this.theFSM[newState].Enter(args); this.m_currentState = newState;//更改当前状态 this.theFSM[newState].Process(args); } } }
代码2:
using System; namespace ShiHuanJue.FSM { public interface IState { // 进入该状态 void Enter(params Object[] args); // 离开状态 void Exit(params Object[] args); // 状态处理 void Process(params Object[] args); } }
代码3:
namespace ShiHuanJue.FSM { // 状态 static public class MotionState { static readonly public string IDLE = "idle"; static readonly public string WALKING = "walking"; static readonly public string DEAD = "dead"; static readonly public string ATTACKING = "attacking"; } }
代码就上面3个,很简单吧。
怎么用呢?
using System; using System.Collections; namespace ShiHuanJue.FSM { static public class RoleStateSet { static public RoleIdle stateIdle = new RoleIdle(); static public RoleWalking stateWalking = new RoleWalking(); static public RoleDead stateDead = new RoleDead(); static public RoleAttacking stateAttackint = new RoleAttacking(); } public class FSMRole : FSMParent { public FSMRole() { theFSM.Add(MotionState.IDLE, RoleStateSet.stateIdle); theFSM.Add(MotionState.WALKING, RoleStateSet.stateWalking); theFSM.Add(MotionState.DEAD, RoleStateSet.stateDead); theFSM.Add(MotionState.ATTACKING, RoleStateSet.stateAttackint); } public override void ChangeStatus(string newState, params Object[] args) { base.ChangeStatus(newState,args); } } }
实现各个状态的逻辑。这里就贴一个Idle的。其它状态格式都一样,只是实现不一样。
using UnityEngine; using System.Collections; namespace ShiHuanJue.FSM { public class RoleIdle : IState { public void Enter(params System.Object[] args) { Debug.Log("RoleIdle Enter"); } public void Exit(params System.Object[] args) { Debug.Log("RoleIdle Exit"); } public void Process(params System.Object[] args) { Debug.Log("RoleIdle Process"); } } }
测试一下咯:
using UnityEngine; using System.Collections; using ShiHuanJue.FSM; public class Test : MonoBehaviour { void Start() { FSMRole roleAI = new FSMRole(); Debug.Log(roleAI.m_currentState); roleAI.ChangeStatus(MotionState.IDLE); Debug.Log(roleAI.m_currentState); roleAI.ChangeStatus(MotionState.WALKING); Debug.Log(roleAI.m_currentState); roleAI.ChangeStatus(MotionState.IDLE); Debug.Log(roleAI.m_currentState); } }
代码都在这了,实际用的也不多,工程就不上传了。用的不多,只是在这记一笔。
实际开发中,还是推荐用行为树。
行为树下次再说,我会先自己写一个行为树之后,分析下缺点,然后介绍一下腾讯开源的行为树框架。
我觉得学习,再理解了它的原理之后,就可以拿现有完善的框架来用,站在巨人的肩膀上,你才可以看的更远,知道自己是多么的渺小。
敬请期待~!
- 本文固定链接: http://www.shihuanjue.com/?p=75
- 转载请注明: 乔 2015年09月04日 于 是幻觉 发表