面向对象状态机框架

这里写图片描述
1.状态类(Istate)当前状态下所有要执行的动作

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace FSM
{
    /// <summary>
    /// 状态接口
    /// </summary>
    public interface Istate
    {
        /// <summary>
        /// 状态名
        /// </summary>
        string Name { get; }
        /// <summary>
        /// 状态标签
        /// </summary>
        string Tag { set; get; }
        /// <summary>
        /// 当前状态的状态机
        /// </summary>
        IstateMachine Parent { get; set; }
        /// <summary>
        /// 从进入状态开始计算的时长
        /// </summary>
        float Timer { get; }
        /// <summary>
        /// 状态过度当前状态的所有过度
        /// </summary>
        List<ITransition> Transition { get; }
        /// <summary>
        /// 进入状态时的回调
        /// </summary>
        /// <param name="prev">上一个状态</param>
        void EnterCallback(Istate prev);
        /// <summary>
        /// 退出状态时的回调
        /// </summary>
        /// <param name="next">下一个状态</param>
        void ExitCallback(Istate next);
        /// <summary>
        /// Update的回调
        /// </summary>
        /// <param name="deltaTime">Time.deltaTime</param>
        void UpdateCallback(float deltaTime);
        /// <summary>
        /// LateUpdate的回调
        /// </summary>
        /// <param name="deltaTime">Time.deltaTime</param>
        void LateUpdateCallback(float deltaTime);
        /// <summary>
        /// FixUppdate的回调
        /// </summary>
        void FixUppdateCallback();
        /// <summary>
        /// 添加过度
        /// </summary>
        /// <param name="t">状态过度</param>
        void AddTransition(ITransition t);


    }
}

1.1状态类实现

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FSM
{
    public delegate void LexDelegate();
    public delegate void LexDelegateState(Istate State);
    public delegate void LexDelegateFloat(float f);
    public class LexState : Istate
    {
        /// <summary>
        /// 当进入状态时调用的事件
        /// </summary>
        public event LexDelegateState OnEnter;
        /// <summary>
        /// 当离开状态时调用的事件
        /// </summary>
        public event LexDelegateState OnExit;
        /// <summary>
        /// 当Update时调用的事件
        /// </summary>
        public event LexDelegateFloat OnUpdate;
        /// <summary>
        /// 当LateUpdate时调用的事件
        /// </summary>
        public event LexDelegateFloat OnLateUpdate;
        /// <summary>
        /// 当FixUpdate时调用的事件
        /// </summary>
        public event LexDelegate OnFixUpdate;
        private string _name;//状态名
        private string _tag;//状态标签
        private IstateMachine _parent;//当前状态的状态机
        private float _Timer;//计时器
        private List<ITransition> _transition;//状态过度
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="name">状态名</param>
        public LexState(string name)
        {
            _name = name;
            _transition = new List<ITransition>();
        }
        /// <summary>
        /// 状态名
        /// </summary>
        public string Name
        {
            get
            {
                return _name;
            }
        }
        /// <summary>
        /// 状态标签
        /// </summary>
        public string Tag
        {
            get
            {
                return _tag;
            }

            set
            {
                _tag = value;
            }
        }
        /// <summary>
        /// 当前状态的状态机
        /// </summary>
        public IstateMachine Parent
        {
            get
            {
                return _parent;
            }

            set
            {
                _parent = value;
            }
        }
        /// <summary>
        /// 从进入状态开始计算的时长
        /// </summary>
        public float Timer
        {
            get
            {
                return _Timer;
            }
        }
        /// <summary>
        /// 状态过度当前状态的所有过度
        /// </summary>
        public List<ITransition> Transition
        {
            get
            {
                return _transition;
            }
        }
        /// <summary>
        /// 添加过度
        /// </summary>
        /// <param name="t">状态过度</param>
        public void AddTransition(ITransition t)
        {
            if(t!=null&&!_transition.Contains(t))
            {
                _transition.Add(t);
            }
        }

        /// <summary>
        /// 进入状态时的回调
        /// </summary>
        /// <param name="prev">上一个状态</param>
        public virtual void EnterCallback(Istate prev)
        {
            //重置计时器
            _Timer = 0;
            //进入状态时系统调用OnEnter事件
            if (OnEnter != null)
            {
                OnEnter(prev);
            }
        }
        /// <summary>
        /// 退出状态时的回调
        /// </summary>
        /// <param name="next">下一个状态</param>
        public virtual void ExitCallback(Istate next)
        {
            //离开状态时系统调用OnEnter事件
            if (OnExit != null)
            {
                OnExit(next);
            }
            //重置计时器
            _Timer = 0;
        }
        /// <summary>
        /// Update的回调
        /// </summary>
        /// <param name="deltaTime">Time.deltaTime</param>
        public virtual void UpdateCallback(float deltaTime)
        {
            //累加计时器
            _Timer += deltaTime;
            //Update时系统会调用OnUpdate事件
            if (OnUpdate!=null)
            {
                OnUpdate(deltaTime);
            }
        }
        /// <summary>
        /// LateUpdate的回调
        /// </summary>
        /// <param name="deltaTime">Time.deltaTime</param>
         public virtual void LateUpdateCallback(float deltaTime)
        {
            //LateUpdate时系统会调用OnLateUpdate事件
            if (OnLateUpdate!=null)
            {
                OnLateUpdate(deltaTime);
            }
        }

        /// <summary>
        /// FixUppdate的回调
        /// </summary>
        public virtual void FixUppdateCallback()
        {
            //FixUpdate时系统会调用OnFixUpdate事件
            if (OnFixUpdate!=null)
            {
                OnFixUpdate();
            }
        }

    }
}

2.状态机类(IstateMachine)当前状态机类中的所有状态

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FSM
{
    /// <summary>
/// 状态机接口
/// </summary>
    public interface IstateMachine
    {
        /// <summary>
        /// 当前状态
        /// </summary>
        Istate CurrentState { get; }
        /// <summary>
        /// 默认状态
        /// </summary>
        Istate DefaultState { set; get; }
        /// <summary>
        /// 添加状态
        /// </summary>
        /// <param name="state">要添加的状态</param>
        void AddState(Istate state);
        /// <summary>
        /// 删除状态
        /// </summary>
        /// <param name="state">要删除的状态</param>
        void RemoveState(Istate state);
        /// <summary>
        /// 通过指定的tag值查找状态
        /// </summary>
        /// <param name="tag">状态 Tag值</param>
        /// <returns>查找到的状态</returns>
        Istate GetStateWithTage(string tag);
    }

}

2.1状态机类实现

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FSM
{
    /// <summary>
    /// 状态机类需要继承与状态类并实现状态机接口
    /// </summary>
    public class LexStateMachine : LexState, IstateMachine
    {
        private Istate _CurrentState;//当前状态
        private Istate _DefaultState;//默认状态
        private List<Istate> _States;//所有状态


        private bool _isTransition = false;//是否正在过度
        private ITransition _t;//当前正在执行的过度
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="name"></param>
        public LexStateMachine(string  name,Istate defaultState):base(name)
        {
            _States = new List<Istate>();
            _DefaultState = defaultState;
        }
        /// <summary>
        /// 当前状态
        /// </summary>
        public Istate CurrentState
        {
            get
            {
                return _CurrentState;
            }
        }
        /// <summary>
        /// 默认状态
        /// </summary>
        public Istate DefaultState
        {
            get
            {
                return _DefaultState;
            }

            set
            {
                AddState(value);
                _DefaultState = value;
            }
        }
        /// <summary>
        /// 添加状态
        /// </summary>
        /// <param name="state">要添加的状态</param>
        public void AddState(Istate state)
        {
            if(state!=null &&!_States.Contains(state))
            {
                _States.Add(state);
                //将加入的新状态的的Parent设置为当前状态机
                state.Parent = this;
                if(_DefaultState==null)
                {
                    _DefaultState = state;
                }
            }
        }
        /// <summary>
        /// 删除状态
        /// </summary>
        /// <param name="state">要删除的状态</param>
        public void RemoveState(Istate state)
        {
            //再状态机运行过程中不能够删除当前状态
            if (_CurrentState == state)
            {
                return;
            }
            if (state != null && _States.Contains(state))
            {
                _States.Remove(state);
                //将已经移除的Parent设置为空
                state.Parent = null;
                if (_DefaultState == state)
                {
                    _DefaultState = (_States.Count >= 1) ? _States[0] : null;
                }
            }
        }
        /// <summary>
        /// 通过指定的tag值查找状态
        /// </summary>
        /// <param name="tag">状态 Tag值</param>
        /// <returns>查找到的状态</returns>
        public Istate GetStateWithTage(string tag)
        {
            return null;
        }
        public override void UpdateCallback(float deltaTime)
        {
            //检测当前是否再过度状态
            if(_isTransition)
            {
                //检测当前执行的过度是否完成
                if(_t.TransitionCallback())
                {
                    DoTransition(_t);
                    _isTransition = false;
                }
                return;
            }
            base.UpdateCallback(deltaTime);
            if(_CurrentState==null)
            {
                _CurrentState = _DefaultState;
            }
            List<ITransition> ts = _CurrentState.Transition;
            int Count = _CurrentState.Transition.Count;
            for (int i = 0; i < Count; i++)
            {
                ITransition t = ts[i];
                if(t.ShouldBengin())
                {
                    _isTransition = true;
                    _t = t;
                    return;
                }
            }
            _CurrentState.UpdateCallback(deltaTime);
        }
        public override void LateUpdateCallback(float deltaTime)
        {
            base.LateUpdateCallback(deltaTime);
            _CurrentState.LateUpdateCallback(deltaTime);
        }
        public override void FixUppdateCallback()
        {
            base.FixUppdateCallback();
            _CurrentState.FixUppdateCallback();
        }
        //开始执行过度
        private void DoTransition(ITransition t)
        {
            _CurrentState.ExitCallback(t.To);
            _CurrentState = t.To;
            _CurrentState.EnterCallback(t.From);
        }
    }
}

3.状态的转换过度类接口(ITransition)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace FSM
{
    /// <summary>
/// 状态过度的接口
/// </summary>
    public interface ITransition
    {
        /// <summary>
        /// 过度名
        /// </summary>
        string name { get; }
        /// <summary>
        /// 从哪个状态开始过度
        /// </summary>
        Istate From { get; set; }
        /// <summary>
        /// 要过度到哪个状态去
        /// </summary>
        Istate To { get; set; }
        /// <summary>
        /// 过度时的回调
        /// </summary>
        /// <returns>返回true过度结束返回false继续进行过度</returns>
        bool TransitionCallback();
        /// <summary>
        /// 能否开始过度
        /// </summary>
        /// <returns>如果是True就开始进行过度如果是False就不进行过度</returns>
        bool ShouldBengin();

    }
}

3.1状态过渡

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FSM
{
    public delegate bool LexTransitionDelegate();
    public class LexTransition : ITransition
    {
        private Istate _From;//原状态
        private Istate _To;//目标状态
        private string _name;//过度名
        public event LexTransitionDelegate OnTransition;
        public event LexTransitionDelegate OnCheck;//检测条件是否满足
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="Name"></param>
        /// <param name="fromstate"></param>
        /// <param name="tostate"></param>
        public LexTransition(string Name, Istate fromstate, Istate tostate)
        {
            _name = Name;
            _From = fromstate;
            _To = tostate;

        }
        /// <summary>
        /// 过度名
        /// </summary>
        public string name
        {
            get
            {
                return _name;
            }
        }

        /// <summary>
        /// 从哪个状态开始过度
        /// </summary>
        public Istate From
        {
            get
            {
                return _From;
            }

            set
            {
                _From = value;
            }
        }
        /// <summary>
        /// 要过度到哪个状态去
        /// </summary>
        public Istate To
        {
            get
            {
                return _To;
            }
            set
            {
                _To = value;
            }
        }
        /// <summary>
        /// 过度时的回调
        /// </summary>
        /// <returns>返回true过度结束返回false继续进行过度</returns>
        public bool TransitionCallback()
        {
            if (OnTransition != null)
            {
                return OnTransition();
            }
            return true;
        }
        /// <summary>
        /// 能否开始过度
        /// </summary>
        /// <returns>如果是True就开始进行过度如果是False就不进行过度</returns>
        public bool ShouldBengin()
        {
            if (OnCheck != null)
            {
                return OnCheck();
            }
            return false;
        }
    }

}

4.调用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FSM;

public class Test : MonoBehaviour {

    public float speed; //Cube每秒钟移动的距离
    private LexStateMachine _fsm;//状态机
    private LexState Idle;//闲置状态
    private LexState move;//移动状态
    private LexTransition _IdleToMove;//Idle到Move的状态过度
    private LexTransition _MoveToIdle;//Move到Idle的状态过度
    private bool IsMove=false;//能否开始移动
    // Use this for initialization
    void Start () {
        //初始化状态
        Idle = new LexState("Idle");//创建状态
        Idle.OnEnter += (Istate state) =>
          {
              Debug.Log("进入Idle状态");
        };

        move = new LexState("Move");
        //移动状态的时候的逻辑
        move.OnUpdate += (float f) =>
          {
              transform.position += transform.forward * f * speed;
          };

        _IdleToMove = new LexTransition("idlemove", Idle, move);//创建过渡状态
        _IdleToMove.OnCheck += () =>
          {
              return IsMove;
          };
        Idle.AddTransition(_IdleToMove);//加入过渡状态链表
        //_IdleToMove.OnTransition += () =>
        //  {

        //  };
        _MoveToIdle = new LexTransition("moveIdle", move, Idle);
        _MoveToIdle.OnCheck += () =>
        {
            return !IsMove;
        };
        move.AddTransition(_MoveToIdle);
        _fsm = new LexStateMachine("Root", Idle);//创建状态机并加入状态
        _fsm.AddState(move);

    }

    // Update is called once per frame
    void Update () {
        _fsm.UpdateCallback(Time.deltaTime);

    }
    void OnGUI()
    {
        if(GUILayout.Button("move"))
        {
            IsMove = true;
        }
        if(GUILayout.Button("Stop"))
        {
            IsMove = false;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FSM;

public class LightControl : MonoBehaviour {

    public float maxIntensity;
    public float FadeSpeed;


    private LexStateMachine _fsm;
    private LexStateMachine _open;//open状态下的子状态声明
    private LexState _close;
    private LexTransition opentoclose;
    private LexTransition closetoopen;
    private LexState _changeIntensity;
    private LexState _changeColor;
    private LexTransition colortointensity;
    private LexTransition intensitytocolor;
    private bool isOpen=true;
    private bool isAnimation;
    private bool isResst;
    private float target;
    private Color targetColor;
    private Color StartColor;
    private float ColorTimer;
    public bool ischangecolor;


    private Light _light;
    // Use this for initialization
    void Start () {
        InitFSM();
        _light = GetComponent<Light>();


    }

    // Update is called once per frame
    void Update () {
        _fsm.UpdateCallback(Time.deltaTime);

    }
    //初始化状态机
    private void InitFSM()
    {
        _changeIntensity = new LexState("changeIntensity");
        _changeIntensity.OnEnter += (Istate State) =>
          {
              isAnimation = true;
              isResst = true;
          };
        _changeIntensity.OnUpdate += (float f) =>
        {
            if (isAnimation)
            {
                if (isResst)
                {
                    if (Fadeto(maxIntensity))
                    {
                        isResst = false;
                        isAnimation = false;
                    }
                }
                else
                {
                    if (Fadeto(target))
                    {
                        isResst = true;
                    }
                }
            }
            else
            {
                target = Random.Range(0.3f, 0.7f);
                isAnimation = true;
            }
        };
        _changeColor = new LexState("changeColor");
        _changeColor.OnEnter += (Istate State) =>
          {
              isAnimation = false;
          };
        _changeColor.OnUpdate += (float f) =>
          {
              if(isAnimation)
              {
                  if(ColorTimer>=1f)
                  {
                      isAnimation = false;
                  }
                  else
                  {
                      ColorTimer += Time.deltaTime ;
                      _light.color = Color.Lerp(StartColor, targetColor, ColorTimer);
                  }
              }
              else
              {
                  float r = Random.Range(0,0.5f);
                  float g = Random.Range(0, 0.5f);
                  float b = Random.Range(0, 0.5f);
                  targetColor = new Color(r, g, b);
                  StartColor = _light.color;
                  ColorTimer = 0f;
                  isAnimation = true;
              }
          };
        colortointensity = new LexTransition("colortointensity",_changeColor,_changeIntensity);
        colortointensity.OnCheck += () =>
        {
            return !ischangecolor;
        };
        _changeColor.AddTransition(colortointensity);

        intensitytocolor = new LexTransition("intensitytocolor", _changeIntensity, _changeColor);
        intensitytocolor.OnCheck += () =>
        {
            return ischangecolor;
        };
        _changeIntensity.AddTransition(intensitytocolor);
        _open = new LexStateMachine("open", _changeIntensity);//子状态的加入
        _open.AddState(_changeColor);     
        _close = new LexState("close");
        _close.OnEnter += (Istate State) =>
        {
            _light.intensity = 0;
        };
        opentoclose = new LexTransition("OpenClose", _open, _close);
        opentoclose.OnCheck += () =>
        {
            return !isOpen;
        };
        //opentoclose.OnTransition += () =>
        //{
        //    return Fadeto(0);
        //};
        _open.AddTransition(opentoclose);
        closetoopen = new LexTransition("CloseOpen", _close, _open);
        closetoopen.OnCheck += () =>
        {
            return isOpen;
        };
        closetoopen.OnTransition += () =>
        {
            return Fadeto(maxIntensity);
        };
        _close.AddTransition(closetoopen);
        _fsm = new LexStateMachine("Cube", _open);
        _fsm.AddState(_close);
    }
    void OnGUI()
    {
        if (GUI.Button(new Rect(150f,30f,55f,28f),"open"))
        {
            isOpen = true;
        }
        if (GUI.Button(new Rect(150f, 65f, 55f, 28f), "Close"))
        {
            isOpen = false;
        }
    }
    //将灯光光强渐变到指定的值
    private bool Fadeto(float f)
    {

        if(Mathf.Abs(_light.intensity-f)<=0.05f)
        {
            _light.intensity = f;
            return true;
        }
        else
        {
            int flag = _light.intensity > f ? -1 : 1;
            _light.intensity += Time.deltaTime * FadeSpeed*flag;
            return false;
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FSM;

public class CubeMoveState : LexState
{
    public CubeMoveState() : base("CubeMoveState")
    {
    }
    public override void EnterCallback(Istate prev)
    {
        //进入移动状态打印上一个状态的名字
        Debug.Log(prev.Name);
    }
    public override void UpdateCallback(float deltaTime)
    {
       //每当处于move状态每帧使用这个方法
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值