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