面向对象状态机框架
来源:互联网 发布:淘宝自然流量没有了 编辑:程序博客网 时间:2024/06/06 01:08
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 0
- 面向对象状态机框架
- 状态机框架
- QTP面向对象框架
- 面向对象设计框架
- lua面向对象与基于lua的状态机实现
- OpenGL面向对象程序框架
- 面向对象模式与框架
- 自定义面向对象数据库框架
- 面向对象框架封装思路
- QT状态机框架
- Qt 状态机框架学习
- hadoop 0.23 状态机框架
- qt状态机框架
- Qt状态机框架
- QT状态机框架
- Qt Qml状态机框架
- 状态机,消息循环,框架
- 状态机FSM代码框架
- Android SurfaceFligner Vsync信号 Jni/C++调用实现
- OplogThread: Last entry no longer in oplog cannot recover!
- 堆排序算法的实现(HeapSort)
- 转-C++快速入门
- scrapy爬虫的暂停与重启
- 面向对象状态机框架
- 如何做到phpmyadmin中最大限制:2,048KB 解决办法
- OpenCV-将图像作平滑处理并显示
- Wait waitpid
- 【Android】 点击空白处隐藏(收起)键盘
- BZOJ 3594 [Scoi2014]方伯伯的玉米田 动态规划+二维树状数组
- Java使用顺序存储实现队列
- 双节连壁,iMindMap钜惠来袭
- Java设计模式——命令模式(Command Pattern)