码迷,mamicode.com
首页 > 编程语言 > 详细

Unity有限状态机编写

时间:2017-01-09 23:30:44      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:oss   start   led   generic   register   多个   改变   状态机   contain   

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

         }

}

 

Unity有限状态机编写

标签:oss   start   led   generic   register   多个   改变   状态机   contain   

原文地址:http://www.cnblogs.com/mzwl/p/6266690.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!