zoukankan      html  css  js  c++  java
  • Unity有限状态机编写

    有限状态机FSM

    是对行为逻辑的抽象。

    在整个FSM架构中

    首先有一个状态基类stateObject

    里面有三个方法,分别是状态前、状态中、状态后。

    所有具体行为类都要继承这个基类,在这三个方法中具体实现各种方法的逻辑。

    然后,需要一个stateManager(大脑)状态管理类来管理这些状态,特别注意的是里面changeState方法,他是状态跳转的关键。

    至于如果存储各种状态,你可以用list类 ,字典类等等。

    写法:

    建类:确认一共有几个状态,新建对应的几个类,还有他的Manager(管理类)和父类State

    代码:

    1.在父类中先public一个管理类类型的变量,为的是让每个状态对应一个状态管理者。然后写状态前,状态中,状态后三个方法。注意这三个方法的类型为virtual,方便子类进行重写。

    因为状态前后都只执行一次,所以返回值为void。状态中的返回值类型为该类类型,可以先返回空值。

    2.让所有状态类继承该父类,并对里面的方法进行重写。在三个方法中添加自己的行为逻辑。注意在状态中的return中返回this(当前状态自身)

    3.写管理类(重点):

    1)首先管理类也要继承该父类。可以做成状态字典,存储对象的所有状态,只有在这个状态字典中才可以转换调用。注意,如果要使用字典必须using System.Collection.Generic。字典写法:Dictionary<string, State> stateDic;

    String用来传状态名称,State为当前状态所有对象。然后定义当前状态:State currentState;

    和上一个状态:State lastState;

    2)在构造器中进行初始化stateDic = new Dictionary<string, State>();

    using UnityEngine;

    using System.Collections;

    using System.Collections.Generic;

     

    public class StateManager : State

    {

        //状态管理类 用字典,是功能类

        //状态字典,存储对象的所有状态,只有在这个状态字典中才可以转换调用

        Dictionary<string, State> stateDic;

        //当前状态

        State currentState;

        //上一个状态

        State lastState;

     

        //初始化放在构造器中

        public StateManager()

        {

            stateDic = new Dictionary<string, State>();

        }

        //注册状态,需要状态名字和状态参数的形参

        public void RegisterState(string stateName, State state)

        {

            //每一次注册一个状态时,就指定这个状态的状态管理者的字段对应注册的这个对象

            //this指代当前类对象实例Dictionary<string, State>(),谁.RegisterState就是谁

            //作用是让一个对象的多个状态都指向同一个管理者

            state.stateManager = this;

            //向状态字典中添加,传递形参状态

            stateDic.Add(stateName, state);

        }

        //设置默认状态,传递状态名为形参

        public void SetDefaultState(string stateName)

        {

            //判断方法列表是否包含这样的一个状态(key值)

            if (!stateDic.ContainsKey(stateName))

            {

                Debug.LogError("状态列表无此状态");

            }

            //设置默认状态

            currentState = stateDic[stateName];

        }

        //改变状态

        public void ChangeState(string stateName)

        {

            //判断方法列表是否包含这样的一个状态(key值)

            //改变状态失败

            if (!stateDic.ContainsKey(stateName))

            {

                Debug.LogError("状态列表无此状态,切换失败");

                currentState = lastState;

            }

            //切换成功,更改状态

            currentState = stateDic[stateName];

        }

        //状态的执行

        public void DoState()

        {

            //第一次执行的时候current是设置的默认状态,lastState是空

            if (currentState != lastState)//加入默认状态为sleep//current=sleep;last=null //第2轮.current=eat;last=sleep

            {

                currentState.EnterState();//sleep的进入方法,只执行一次//current=sleep;last=null

                //把后一个状态赋给当前状态,跳出if条件

                lastState = currentState;//current=sleep;last=sleep

            }

            //执行“状态中”

            lastState.StayState();//sleep的持续方法 //current=sleep;last=sleep

            //退出状态                                  //sleep切换为eat//current=eat;last=sleep

            if (lastState != currentState)//current=eat;last=sleep

            {

                lastState.ExitState();          //sleep退出

            }

        }

    }

    然后新建一个挂在游戏物体上的类

    using UnityEngine;

    using System.Collections;

     

    public class FSMManager_Boss : MonoBehaviour {

        StateManager_Boss manager;

             // Use this for initialization

             void Start () {

            manager = new StateManager_Boss();

            // 注册状态

            manager.RegisterState("idle", new IdleState_Boss());

            manager.RegisterState("run", new RunState_Boss());

            manager.RegisterState("attack", new AttackState_Boss());

            manager.RegisterState("Death", new DeathState_Boss());

            //设置初始状态

            manager.SetDefaultState("idle");

             }

            

             // Update is called once per frame

             void Update () {

            manager.DoState();

             }

    }

     

  • 相关阅读:
    实际成本法
    加权平均法,移动加权平均法,先进先出法(计算策略)
    xss缺陷--脚本语言嵌入漏洞
    关于耳机插入,设备管理中:声音设置中却显示"没有耳机插入"
    国家十二类稀缺人才
    apache2.4搭建php5.53问题总结
    任意多个有序结合求交集
    类似于大数相加的一个题
    数字的最大组合
    计算二叉树每层的和
  • 原文地址:https://www.cnblogs.com/mzwl/p/6266690.html
Copyright © 2011-2022 走看看