• 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效果则会用到神经网络算法。如有错误,欢迎指正!

  • 相关阅读:
    深入了解 Flink 网络栈(二):监控、指标和处理背压
    物联网安全技术提高区块链应用数据的可信度
    威胁快报|Bulehero挖矿蠕虫升级,PhpStudy后门漏洞加入武器库
    Ververica Platform-阿里巴巴全新Flink企业版揭秘
    重磅 | 阿里云与MongoDB达成战略合作,成为全球唯一提供最新版MongoDB的云厂商
    阿里巴巴叶军:政企数字化转型,现在是最重要的时机
    Canonical 开源 MicroK8 | 云原生生态周报 Vol. 25
    nyoj42——连通图加欧拉(连通图板子)dfs
    nyoj38——最小生成树
    nyoj20——有向无环图深搜模板
  • 原文地址:https://www.cnblogs.com/IAMTOM/p/10197503.html
Copyright © 2020-2023  润新知