unity之通用FSM有限状态机(一)


什么是有限状态机:

有限状态机是一种用来进行对象行为建模的工具,作用是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件。简单理解就是:状态满足条件下的一种处理机制。

有限状态机,任意时刻都处于有限状态集合中的某一状态。当获得一个输入字符时,将从当前状态转换到另一状态或仍保持当前状态。

每一个状态都有三种行为:进入、 执行、 离开。

 

对状态机有一个简单的了解之后,那么状态机在unity游戏开发中有哪些应用呢?

大多游戏都有以下流程:

这些流程,我们是不是可以理解为状态。

在AI 方面,游戏中的玩家行为大致有以下状态:

站立(待机)、跑、跳、普攻、技能1,技能2,技能3,受伤、控制(眩晕、禁锢)、死亡 等等

 

以上2种举例都可体现有限状态机在游戏中的应用。故设计通用的状态机就显得很有必要。而不是为每一个应用都写一个状态机。

 

废话不多说,直接上代码

状态机基类:都存在编号、当前状态 抽象到基类。

 1 public abstract class TestFsmBase  2 {  3     /// <summary>
 4     /// 状态机编号  5     /// </summary>
 6     public int FsmId { get; private set; }  7 
 8     /// <summary>
 9     /// 状态机当前的状态 10     /// </summary>
11     public sbyte CurrState; 12 
13 
14     public TestFsmBase(int fsmId) 15  { 16         FsmId = fsmId; 17  } 18 
19     /// <summary>
20     /// 关闭 21     /// </summary>
22     public abstract void ShutDown(); 23 }

 

状态机状态:进入  执行 离开  最基本的三种行为。

 1 public class TestFsmState<T> where T : class
 2 {  3     public TestFsm<T> CurrFsm;  4 
 5     public virtual void OnEnter()  6  {  7  }  8 
 9     public virtual void OnUpdate() 10  { 11  } 12 
13     public virtual void OnLeave() 14  { 15  } 16 
17     public virtual void OnDestroy() 18  { 19 
20  } 21 }

 

状态机:

1.状态机的拥有者

2.状态机都有哪些状态

3.切换状态

4.关闭状态机

 1 using System.Collections.Generic;  2 
 3 public class TestFsm<T> : TestFsmBase where T : class
 4 {  5     /// <summary>
 6     /// 状态机拥有者  7     /// </summary>
 8     public T Owner { get; private set; }  9 
10     public TestFsmState<T> m_CurrFsmState; 11 
12     public Dictionary<sbyte, TestFsmState<T>> m_StateDic; 13 
14 
15     public TestFsm(int fsmId, T owner, TestFsmState<T>[] status) : base(fsmId) 16  { 17         Owner = owner; 18         m_StateDic = new Dictionary<sbyte, TestFsmState<T>>(); 19         for (int i = 0; i < status.Length; i++) 20  { 21             m_StateDic[(sbyte)i] = status[i]; 22             status[i].CurrFsm = this;//状态的状态机就是Fsm本身
23  } 24         CurrState = -1; 25  } 26 
27     /// <summary>
28     /// 获取状态 29     /// </summary>
30     /// <returns></returns>
31     public TestFsmState<T> GetState(sbyte stateType) 32  { 33         m_StateDic.TryGetValue(stateType, out TestFsmState<T> fsmState); 34         return fsmState; 35  } 36 
37     /// <summary>
38     /// 切换状态 39     /// </summary>
40     /// <param name="newState"></param>
41     public void ChangeState(sbyte newState) 42  { 43         //上一个状态离开 新状态进入
44         if (newState == CurrStateType) return; 45         if (m_CurrFsmState != null) 46  { 47  m_CurrFsmState.OnLeave(); 48  } 49         if (m_StateDic.TryGetValue(newState, out TestFsmState<T> newFsmState)) 50  { 51             CurrState = newState; 52             m_CurrFsmState = newFsmState; 53  m_CurrFsmState.OnEnter(); 54  } 55  } 56 
57     public void OnUpdate() 58  { 59         if (m_CurrFsmState != null) 60  { 61  m_CurrFsmState.OnUpdate(); 62  } 63  } 64 
65     /// <summary>
66     /// 关闭状态机 67     /// </summary>
68     public override void ShutDown() 69  { 70         if (m_CurrFsmState != null) 71  { 72  m_CurrFsmState.OnLeave(); 73  } 74         var enumerator = m_StateDic.GetEnumerator(); 75         while (enumerator.MoveNext()) 76  { 77  enumerator.Current.Value.OnDestroy(); 78  } 79  m_StateDic.Clear(); 80  } 81 }

 

状态机管理器:.创建 、存在、 销毁

 1 using System;  2 using System.Collections.Generic;  3 
 4 /// <summary>
 5 /// 状态机管理器  6 /// </summary>
 7 public class TestFsmManager : IDisposable  8 {  9     private int m_tempFsmId = 1; 10     private readonly Dictionary<int, TestFsmBase> fmsDic; 11 
12     public TestFsmManager() 13  { 14         fmsDic = new Dictionary<int, TestFsmBase>(); 15  } 16 
17     /// <summary>
18     /// 创建 19     /// </summary>
20     /// <typeparam name="T"></typeparam>
21     /// <param name="own"></param>
22     /// <param name="status"></param>
23     /// <returns></returns>
24     public TestFsm<T> CreateFsm<T>(T owner, TestFsmState<T>[] status) where T : class
25  { 26         TestFsm<T> fsm = new TestFsm<T>(m_tempFsmId++, owner, status); 27         fmsDic[m_tempFsmId] = fsm; 28         return fsm; 29  } 30 
31     /// <summary>
32     /// 是否存在 33     /// </summary>
34     /// <param name="fsmId"></param>
35     /// <returns></returns>
36     public bool HasFsm(int fsmId) 37  { 38         return fmsDic.ContainsKey(fsmId); 39  } 40 
41     /// <summary>
42     /// 销毁 43     /// </summary>
44     /// <param name="fsmId"></param>
45     public void DestroyFsm(int fsmId) 46  { 47         if (fmsDic.TryGetValue(fsmId, out TestFsmBase fsmBase)) 48  { 49  fsmBase.ShutDown(); 50  fmsDic.Remove(fsmId); 51  } 52  } 53 
54     public void Dispose() 55  { 56         var enumerator = fmsDic.GetEnumerator(); 57         while (enumerator.MoveNext()) 58  { 59  enumerator.Current.Value.ShutDown(); 60  } 61  fmsDic.Clear(); 62  } 63 }

 

接下来,讲解下状态机在流程应用方面是如何使用的。

unity之通用FSM有限状态机 —>流程管理的使用(二)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM