有限状态机(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);
    }
}

代码都在这了,实际用的也不多,工程就不上传了。用的不多,只是在这记一笔。
实际开发中,还是推荐用行为树。
行为树下次再说,我会先自己写一个行为树之后,分析下缺点,然后介绍一下腾讯开源的行为树框架。
我觉得学习,再理解了它的原理之后,就可以拿现有完善的框架来用,站在巨人的肩膀上,你才可以看的更远,知道自己是多么的渺小。
敬请期待~!

posted @ 2016-05-13 11:37  Joe师傅  阅读(464)  评论(0编辑  收藏  举报