zoukankan      html  css  js  c++  java
  • FSM有限状态机

    1、什么是有限状态机

    有限状态机(Finite State Machine),简称FSM,它由一组有限个状态、输入和根据输入及现有状态转换为下一个状态的转换函数组成,当然,通常每个状态机都必须有一个初始状态。它有两个重要的概念:状态和转移。有限状态机在很多领域都有运用,这里介绍的是在unity游戏开发中的运用。在游戏开发中,通常使用FSM去实现一些简单的AI逻辑,对于游戏中的每个对象,都可以在其生命周期中分出一些状态,比如一个小兵,它可能在休息,或者是在巡逻,当有敌人出现时,它的状态会变成追逐或者攻击敌人。当某些条件成立时,状态机从当前状态转移到下一个状态,在不同的状态下,游戏对象执行不同的任务。有限状态机中必须注意的是:必须要有一个初始状态,并保存当前状态,以及注意每个状态转移的必要条件。下面动手写一个简易的unity有限状态机。
     

    2、定义有限状态机基类

    public class FSMStateBase {
        //进入该状态时调用
        public virtual void Enter() { }
    
        //每帧调用
        public virtual void Update() { }
    
        //退出该状态时调用
        public virtual void Exit() { }
    }

    3、定义一组具体状态

    public class IdleState : FSMStateBase {
        public override void Enter()
        {
            
        }
        public override void Update()
        {
            
        }
        public override void Exit()
        {
            
        }
    }
    
    public class WalkState : FSMStateBase
    {
        public override void Enter()
        {
    
        }
        public override void Update()
        {
    
        }
        public override void Exit()
        {
    
        }
    }
    
    public class AttackState : FSMStateBase
    { 
        public override void Enter()
        {
    
        }
        public override void Update()
        {
    
        }
        public override void Exit()
        {
    
        }
    }

    4、有限状态机使用示例

    public class FSMManager : MonoBehaviour {
    
       public enum State {
            Walk,
            Idle,
            Attack
        }
    
        private State curState;//当前状态
        private Dictionary<State, FSMStateBase> fsmDict = new Dictionary<State, FSMStateBase>();
    
        private void Start()
        {
            curState = State.Idle;
            InitState();
        }
    
        //添加一组状态
        public void InitState()
        {
            fsmDict.Add(State.Walk, new WalkState());
            fsmDict.Add(State.Idle, new IdleState());
            fsmDict.Add(State.Attack, new AttackState());
        }
    
        //转移状态
        public void ChangeState(State state)
        { 
            fsmDict[curState].Exit();
            curState = state;
            fsmDict[curState].Enter();
        }
    
        private void Update()
        {
            //模拟转换条件
            if (Input.GetKeyDown(KeyCode.A))
            {
                ChangeState(State.Walk);
            }
            else if (Input.GetKeyDown(KeyCode.B))
            {
                ChangeState(State.Attack);
            }
    
            fsmDict[curState].Update();
        }
    
    }

    5、最后

    上面完成了一个简单的FSM有限状态机使用示例,可以看到,状态转移条件判断会有很多if else语句,状态一多,就很容易出bug。可以看出,有限状态机在某条件下,它的转移状态是一i定的,有限状态机有一个变种,叫模糊状态机,在确定的条件下,它的转移状态不是百分百确定的,它有一定的概率会转移到另一个状态。还有其他状态机比如分层状态机,水平有限,这里就不做介绍了。一般有限状态机在unity中只用来做简易的AI,如果要实现复杂的状态逻辑,有限状态机明显会显得力不从心,因此稍微复杂一些的情况我们会使用行为树,一些高级的AI效果则会用到神经网络算法。如有错误,欢迎指正!

  • 相关阅读:
    我自己开发的工具,打印出百度贴吧某用户发表过的所有帖子
    The Smart Field Service Prototype powered by SAP FSM and Wechat
    如何阻止SAP CRM订单创建好之后,自动被置为传输状态这一行为
    C++ Primer读书笔记(3)
    C++ Primer读书笔记(2)
    Coursera台大机器学习技法课程笔记08-Adaptive Boosting
    计算机视觉目标检测的框架与过程(转)
    目标检测的图像特征提取之(一)HOG特征(转)
    Coursera台大机器学习技法课程笔记07-Blending and Bagging
    前景检测(1):VIBE
  • 原文地址:https://www.cnblogs.com/IAMTOM/p/10197503.html
Copyright © 2011-2022 走看看