Unity3d编程,简易状态机(fsm)

来源:互联网 发布:mysql 数据快照 编辑:程序博客网 时间:2024/05/19 11:44

unity3d 简易状态机(fsm)

摘要:
unity3d中很多游戏物体或者程序逻辑会存在很多种状态,通常会采用状态者模式来实现不同状态的切换。下面我们来实现一个简易的状态机(fsm)

  • 简易状态机包含两块:状态(state)和转化(translate)

  • 代码实现

  • (状态类 fsmstate)
public interface IMonoBehaviour{    void Awake();    void Start();    void Update();    void FixedUpdate();    void LateUpdate();}public abstract class FSMState : IMonoBehaviour    {        private string stateName;        public string StateName        {            get            {                return stateName;            }        }        ///该状态能转化到下个状态的状态列表        private List<string> nextStateList = new List<string>();        public int nextStateCount = 0;        public FSMState(string stateName)        {            this.stateName = stateName;        }        public virtual void OnBeforeEnter()        { }        public abstract void OnEnter();        public virtual void OnExit()        { }        public void AddNextState(string nextStateName)        {            if (nextStateList == null)                nextStateList = new List<string>();            if (!nextStateList.Contains(nextStateName))                nextStateList.Add(nextStateName);        }        public void AddNexState(string[] nextStateNames)        {            for (int i = 0; i < nextStateNames.Length;i++ )                AddNextState(nextStateNames[i]);        }        public void RemoveNextState(string nextStateName)        {            if (nextStateList != null && nextStateList.Contains(nextStateName))                nextStateList.Remove(nextStateName);        }        /// <summary>        /// 判断要转换的下个状态是否是当前状态的下一个状态        /// </summary>        /// <param name="nameStateName"></param>        /// <returns></returns>        public bool IsTransition(string nameStateName)        {            if (nextStateList == null || !nextStateList.Contains(nameStateName))            {                //Debug.LogError("要转换的状态:"+nameStateName+"不是当前状态:"+this.stateName+"的下一个状态");                return false;            }            return true;        }        public void Awake()        {        }        public void Start()        {        }        public virtual void Update()        {        }        public virtual void FixedUpdate()        {        }        public virtual void LateUpdate()        {        }    }}

FSM类

using System;using System.Collections.Generic;using System.Linq;using System.Text;using UnityEngine;namespace Framework{    public class FSM : IMonoBehaviour    {        public Dictionary<string, FSMState> stateDic = new Dictionary<string, FSMState>();        private FSMState currentState = null;        public FSMState CurrentState        {            get            {                return currentState;            }            set            {                if (currentState != null)                {                    currentState.OnExit();                    value.OnBeforeEnter();                }                currentState = value;                currentState.OnEnter();            }        }        public void TransitionState(string nextState)        {            if (currentState.IsTransition(nextState))            {                if (stateDic.ContainsKey(nextState))                    this.CurrentState = stateDic[nextState];                else                {                    FSMState state = Activator.CreateInstance(Type.GetType(nextState)) as FSMState;                    stateDic.Add(nextState, state);                    currentState = state;                }            }            else                Debug.LogError("要转换的状态不是当前状态:"+currentState+"的下个状态:"+nextState);        }        public FSMState GetState(string stateName)        {            FSMState state;            stateDic.TryGetValue(stateName, out state);            if (state == null)            {                Debug.LogError("无法得到");                return null;            }            return state;        }        public void AddState(FSMState state)        {            if (stateDic == null)            {                stateDic = new Dictionary<string, FSMState>();            }            if (!stateDic.ContainsKey(state.StateName))            {                stateDic.Add(state.StateName, state);            }        }        public void RemoveState(string stateName)        {            if (stateDic != null)            {                if (stateDic.ContainsKey(stateName))                {                    stateDic.Remove(stateName);                }            }        }        public void Update()        {            if (currentState != null)            {                currentState.Update();            }        }        public void FixedUpdate()        {            if (currentState != null)            {                currentState.FixedUpdate();            }        }        public void LateUpdate()        {            if (currentState != null)            {                currentState.LateUpdate();            }        }        public void Awake()        {        }        public void Start()        {        }    }}

测试代码的话,这里我只做说明
1.对于一个有多种状态的游戏物体,可以为这个游戏物体的每个状态创建一个状态类继承自fsmstate,实现具体的状态细节。
2.在游戏物体脚本中new一个FSM的对象,然后添加所需的状态,并给每个状态添加所能转化的下个状态的列表。
3.初始化当前状态。
4.在物体脚本组件中的update,fixedupdate,lateupdate中调用fsm.update,fsm.fixedupdate等