日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转】有限状态机用法教程

發布時間:2023/12/10 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】有限状态机用法教程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

如博文無法正常顯示,請訪問原文地址:?https://blog.csdn.net/ChinarCSDN/article/details/82263126

?

有限狀態機用法教程

?

文章目錄

  • 有限狀態機用法教程

  • @[toc]
  • 1
  • Finite-state machine?—— 有限狀態機
  • 2
  • Foreword?—— 前言()
  • 3
  • Example?—— 示例
  • 4
  • Moltimode?—— 多狀態
  • 5
  • GameManager?——游戲總控腳本
  • 6
  • View?—— 視圖腳本
  • 7
  • Final effect?—— 最終效果
  • 8
  • Project?—— 項目文件
  • 支持
  • May Be?—— 搞開發,總有一天要做的事!

?

全文高清圖片,點擊即可放大觀看?(很多人竟然不知道)

?


1

Finite-state machine?—— 有限狀態機



有限狀態機簡稱:?FSM?—— 簡稱狀態機

是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型


其他的不多說,對于我們開發者來說,狀態機可以在全局視角下,管理我們的游戲狀態/人物狀態

使我們的工程邏輯清晰,將游戲/項目各個狀態的轉換,交由狀態機統一管理

極大的避免了當狀態過多 / 轉換狀態過多時,每次都需要調用相應函數來完成轉換的麻煩


對于初學者來講,套用狀態機來對狀態進行管理,可能認為過于麻煩

其實不用怕,那只是因為不熟悉用法和邏輯流程導致的

熟練的運用狀態機來管理我們的項目狀態,是很有必要的

那會使后期,我們的工程非常便于維護


2

Foreword?—— 前言()



網上的大神們為了更全面的闡述狀態機的具體工作方式,他們有些說的極為詳細

但對于初學者來講,直接看這樣的圖解,教程,多數都是一臉懵逼

例如:(圖片引用自網絡大神博客)

眾所周知?Chinar?這些大神講的略有不同

Chinar?會通過一些簡單的例子,來帶領初學者了解并學會如何使用狀態機來管理我們的工程.

師傅領進門,修行靠個人 ,一切都需要先入門后,自己再慢慢擴展,不然一切都是扯淡


3

Example?—— 示例



腳本引用自?Wiki.unity3d?——?源碼鏈接

這里?Chinar?用一個簡單的游戲狀態切換邏輯來說明狀態機用法

MVC?設計模式


FSM?一共2個類,不需要掛載到游戲對象上

FSMState?狀態父類,所有子類狀態都繼承于這個類

例如以下工程:我們要需要2個狀態:?菜單狀態 與 游戲狀態

那么這兩個類MenuState 和 GameState都需要繼承自?FSMState



狀態機腳本

<span style="color:#000000"><code class="language-c">using UnityEngine<span style="color:#999999">;</span> using System<span style="color:#999999">.</span>Collections<span style="color:#999999">.</span>Generic<span style="color:#999999">;</span> using UnityEngine<span style="color:#999999">.</span>Experimental<span style="color:#999999">.</span>PlayerLoop<span style="color:#999999">;</span><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// Place the labels for the Transitions in this enum. —— 在此枚舉中放置轉換的標簽。</span> <span style="color:#6272a4">/// Don't change the first label, NullTransition as FSMSystem class uses it. —— 不要改變第一個標簽:NullTransition,因為FSMSystem類使用它。</span> <span style="color:#6272a4">/// </summary></span> public <span style="color:#ff79c6">enum</span> Transition <span style="color:#999999">{</span>NullTransition <span style="color:#6272a4">=</span> <span style="color:#f1fa8c">0</span><span style="color:#999999">,</span> <span style="color:#6272a4">// Use this transition to represent a non-existing transition in your system —— 使用此轉換表示系統中不存在的轉換</span>Game<span style="color:#999999">,</span> <span style="color:#6272a4">//轉到游戲</span>Menu <span style="color:#6272a4">//轉到菜單</span> <span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// Place the labels for the States in this enum. —— 在此枚舉中放置狀態的標簽。</span> <span style="color:#6272a4">/// Don't change the first label, NullStateID as FSMSystem class uses it.不要改變第一個標簽:NullStateID,因為FSMSystem類使用它。</span> <span style="color:#6272a4">/// </summary></span> public <span style="color:#ff79c6">enum</span> StateID <span style="color:#999999">{</span>NullStateId <span style="color:#6272a4">=</span> <span style="color:#f1fa8c">0</span><span style="color:#999999">,</span> <span style="color:#6272a4">// Use this ID to represent a non-existing State in your system —— 使用此ID表示系統中不存在的狀態</span>Menu<span style="color:#999999">,</span> <span style="color:#6272a4">//菜單</span>Game <span style="color:#6272a4">//游戲</span> <span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// This class represents the States in the Finite State System.該類表示有限狀態系統中的狀態。</span> <span style="color:#6272a4">/// Each state has a Dictionary with pairs (transition-state) showing 每個狀態都有一個對顯示(轉換狀態)的字典</span> <span style="color:#6272a4">/// which state the FSM should be if a transition is fired while this state is the current state.如果在此狀態為當前狀態時觸發轉換,則FSM應處于那種狀態。</span> <span style="color:#6272a4">/// Method Reason is used to determine which transition should be fired .方法原因用于確定應觸發哪個轉換。</span> <span style="color:#6272a4">/// Method Act has the code to perform the actions the NPC is supposed do if it's on this state.方法具有執行NPC動作的代碼應該在這種狀態下執行。</span> <span style="color:#6272a4">/// </summary></span> public abstract class FSMState <span style="color:#999999">:</span> MonoBehaviour <span style="color:#999999">{</span>public Dictionary<span style="color:#6272a4"><</span>Transition<span style="color:#999999">,</span> StateID<span style="color:#6272a4">></span> map <span style="color:#6272a4">=</span> new Dictionary<span style="color:#6272a4"><</span>Transition<span style="color:#999999">,</span> StateID<span style="color:#6272a4">></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//字典 《轉換,狀態ID》</span>protected StateID stateID<span style="color:#999999">;</span> <span style="color:#6272a4">//私有ID</span>public StateID ID <span style="color:#6272a4">//狀態ID</span><span style="color:#999999">{</span>get <span style="color:#999999">{</span> <span style="color:#ff79c6">return</span> stateID<span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">}</span>protected GameManager manager<span style="color:#999999">;</span> <span style="color:#6272a4">//保證子類狀態可以訪問到總控 GameManager</span>public GameManager Manager<span style="color:#999999">{</span>set <span style="color:#999999">{</span> manager <span style="color:#6272a4">=</span> value<span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 添加轉換</span><span style="color:#6272a4">/// </summary></span><span style="color:#6272a4">/// <param name="trans">轉換狀態</param></span><span style="color:#6272a4">/// <param name="id">轉換ID</param></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">AddTransition</span><span style="color:#999999">(</span>Transition trans<span style="color:#999999">,</span> StateID id<span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>trans <span style="color:#6272a4">==</span> Transition<span style="color:#999999">.</span>NullTransition<span style="color:#999999">)</span> <span style="color:#6272a4">// Check if anyone of the args is invalid —— //檢查是否有參數無效</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSMState ERROR: NullTransition is not allowed for a real transition"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>id <span style="color:#6272a4">==</span> StateID<span style="color:#999999">.</span>NullStateId<span style="color:#999999">)</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSMState ERROR: NullStateID is not allowed for a real ID"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>map<span style="color:#999999">.</span><span style="color:#8be9fd">ContainsKey</span><span style="color:#999999">(</span>trans<span style="color:#999999">)</span><span style="color:#999999">)</span> <span style="color:#6272a4">// Since this is a Deterministic FSM,check if the current transition was already inside the map —— 因為這是一個確定性FSM,檢查當前的轉換是否已經在字典中</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSMState ERROR: State "</span> <span style="color:#6272a4">+</span> stateID<span style="color:#999999">.</span><span style="color:#8be9fd">ToString</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">+</span> <span style="color:#f1fa8c">" already has transition "</span> <span style="color:#6272a4">+</span> trans<span style="color:#999999">.</span><span style="color:#8be9fd">ToString</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">+</span><span style="color:#f1fa8c">"Impossible to assign to another state"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span>map<span style="color:#999999">.</span><span style="color:#8be9fd">Add</span><span style="color:#999999">(</span>trans<span style="color:#999999">,</span> id<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// This method deletes a pair transition-state from this state's map. —— 該方法從狀態映射中刪除一對轉換狀態。</span><span style="color:#6272a4">/// If the transition was not inside the state's map, an ERROR message is printed. —— 如果轉換不在狀態映射內,則會打印一條錯誤消息。</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">DeleteTransition</span><span style="color:#999999">(</span>Transition trans<span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>trans <span style="color:#6272a4">==</span> Transition<span style="color:#999999">.</span>NullTransition<span style="color:#999999">)</span> <span style="color:#6272a4">// Check for NullTransition —— 檢查狀態是否為空</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSMState ERROR: NullTransition is not allowed"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>map<span style="color:#999999">.</span><span style="color:#8be9fd">ContainsKey</span><span style="color:#999999">(</span>trans<span style="color:#999999">)</span><span style="color:#999999">)</span> <span style="color:#6272a4">// Check if the pair is inside the map before deleting —— 在刪除之前,檢查這一對是否在字典中</span><span style="color:#999999">{</span>map<span style="color:#999999">.</span><span style="color:#8be9fd">Remove</span><span style="color:#999999">(</span>trans<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSMState ERROR: Transition "</span> <span style="color:#6272a4">+</span> trans<span style="color:#999999">.</span><span style="color:#8be9fd">ToString</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">+</span> <span style="color:#f1fa8c">" passed to "</span> <span style="color:#6272a4">+</span> stateID<span style="color:#999999">.</span><span style="color:#8be9fd">ToString</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">+</span><span style="color:#f1fa8c">" was not on the state's transition list"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// This method returns the new state the FSM should be if this state receives a transition and—— 如果該狀態接收到轉換,該方法返回FSM應該為新狀態</span><span style="color:#6272a4">/// 得到輸出狀態</span><span style="color:#6272a4">/// </summary></span>public StateID <span style="color:#8be9fd">GetOutputState</span><span style="color:#999999">(</span>Transition trans<span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>map<span style="color:#999999">.</span><span style="color:#8be9fd">ContainsKey</span><span style="color:#999999">(</span>trans<span style="color:#999999">)</span><span style="color:#999999">)</span> <span style="color:#6272a4">// Check if the map has this transition —— 檢查字典中是否有這個狀態</span><span style="color:#999999">{</span><span style="color:#ff79c6">return</span> map<span style="color:#999999">[</span>trans<span style="color:#999999">]</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#ff79c6">return</span> StateID<span style="color:#999999">.</span>NullStateId<span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// This method is used to set up the State condition before entering it. —— 該方法用于在進入狀態條件之前設置狀態條件。</span><span style="color:#6272a4">/// It is called automatically by the FSMSystem class before assigning it to the current state.—— 在分配它之前,FSMSystem類會自動調用它到當前狀態</span><span style="color:#6272a4">/// </summary></span>public virtual <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">DoBeforeEntering</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 此方法用于在FSMSystem更改為另一個變量之前進行任何必要的修改。在切換到新狀態之前,FSMSystem會自動調用它。</span><span style="color:#6272a4">/// This method is used to make anything necessary, as reseting variables</span><span style="color:#6272a4">/// before the FSMSystem changes to another one. It is called automatically</span><span style="color:#6272a4">/// by the FSMSystem before changing to a new state.</span><span style="color:#6272a4">/// </summary></span>public virtual <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">DoBeforeLeaving</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 這個方法決定狀態是否應該轉換到它列表上的另一個NPC是對這個類控制的對象的引用</span><span style="color:#6272a4">/// This method decides if the state should transition to another on its list</span><span style="color:#6272a4">/// NPC is a reference to the object that is controlled by this class</span><span style="color:#6272a4">/// </summary></span>public virtual <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">Reason</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 這種方法控制了NPC在游戲世界中的行為。</span><span style="color:#6272a4">/// NPC做的每一個動作、動作或交流都應該放在這里</span><span style="color:#6272a4">/// NPC是這個類控制的對象的引用</span><span style="color:#6272a4">/// This method controls the behavior of the NPC in the game World.</span><span style="color:#6272a4">/// Every action, movement or communication the NPC does should be placed here</span><span style="color:#6272a4">/// NPC is a reference to the object that is controlled by this class</span><span style="color:#6272a4">/// </summary></span>public virtual <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">Act</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#999999">}</span> <span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// FSMSystem class represents the Finite State Machine class.FSMSystem類表示有限狀態機類。</span> <span style="color:#6272a4">/// It has a List with the States the NPC has and methods to add, 它句有一個狀態列表,NPC有添加、刪除狀態和更改機器當前狀態的方法。</span> <span style="color:#6272a4">/// delete a state, and to change the current state the Machine is on.</span> <span style="color:#6272a4">/// </summary></span> public class FSMSystem <span style="color:#999999">{</span>private List<span style="color:#6272a4"><</span>FSMState<span style="color:#6272a4">></span> states<span style="color:#999999">;</span> <span style="color:#6272a4">//狀態集</span><span style="color:#6272a4">// The only way one can change the state of the FSM is by performing a transition 改變FSM狀態的唯一方法是進行轉換</span><span style="color:#6272a4">// Don't change the CurrentState directly 不要直接改變當前狀態</span>private StateID currentStateID<span style="color:#999999">;</span>public StateID CurrentStateID<span style="color:#999999">{</span>get <span style="color:#999999">{</span> <span style="color:#ff79c6">return</span> currentStateID<span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">}</span>private FSMState currentState<span style="color:#999999">;</span>public FSMState CurrentState<span style="color:#999999">{</span>get <span style="color:#999999">{</span> <span style="color:#ff79c6">return</span> currentState<span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 默認構造函數</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#8be9fd">FSMSystem</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>states <span style="color:#6272a4">=</span> new List<span style="color:#6272a4"><</span>FSMState<span style="color:#6272a4">></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 設置當前狀態</span><span style="color:#6272a4">/// </summary></span><span style="color:#6272a4">/// <param name="state">初始狀態</param></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">SetCurrentState</span><span style="color:#999999">(</span>FSMState state<span style="color:#999999">)</span><span style="color:#999999">{</span>currentState <span style="color:#6272a4">=</span> state<span style="color:#999999">;</span>currentStateID <span style="color:#6272a4">=</span> state<span style="color:#999999">.</span>ID<span style="color:#999999">;</span>state<span style="color:#999999">.</span><span style="color:#8be9fd">DoBeforeEntering</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//開始前狀態切換</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// This method places new states inside the FSM, —— 這個方法在FSM內部放置一個放置一個新狀態</span><span style="color:#6272a4">/// or prints an ERROR message if the state was already inside the List. —— 或者,如果狀態已經在列表中,則打印錯誤消息。</span><span style="color:#6272a4">/// First state added is also the initial state. 第一個添加的狀態也是初始狀態。</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">AddState</span><span style="color:#999999">(</span>FSMState fsmState<span style="color:#999999">,</span> GameManager manager<span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#6272a4">// Check for Null reference before deleting 刪除前判空</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>fsmState <span style="color:#6272a4">==</span> null<span style="color:#999999">)</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSM ERROR: Null reference is not allowed"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#ff79c6">else</span> <span style="color:#6272a4">// First State inserted is also the Initial state, —— 插入的第一個狀態也是初始狀態,// the state the machine is in when the simulation begins —— 狀態機是在模擬開始時</span><span style="color:#999999">{</span>fsmState<span style="color:#999999">.</span>Manager <span style="color:#6272a4">=</span> manager<span style="color:#999999">;</span> <span style="color:#6272a4">//給每個狀態添加總控 GameManager</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>states<span style="color:#999999">.</span>Count <span style="color:#6272a4">==</span> <span style="color:#f1fa8c">0</span><span style="color:#999999">)</span><span style="color:#999999">{</span>states<span style="color:#999999">.</span><span style="color:#8be9fd">Add</span><span style="color:#999999">(</span>fsmState<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span>foreach <span style="color:#999999">(</span>FSMState state in states<span style="color:#999999">)</span> <span style="color:#6272a4">// Add the state to the List if it's not inside it 如果狀態不在列表中,則將其添加到列表中 (添加狀態ID)</span><span style="color:#999999">{</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>state<span style="color:#999999">.</span>ID <span style="color:#6272a4">==</span> fsmState<span style="color:#999999">.</span>ID<span style="color:#999999">)</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSM ERROR: Impossible to add state "</span> <span style="color:#6272a4">+</span> fsmState<span style="color:#999999">.</span>ID<span style="color:#999999">.</span><span style="color:#8be9fd">ToString</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">+</span><span style="color:#f1fa8c">" because state has already been added"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#999999">}</span>states<span style="color:#999999">.</span><span style="color:#8be9fd">Add</span><span style="color:#999999">(</span>fsmState<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// This method delete a state from the FSM List if it exists, —— 這個方法從FSM列表中刪除一個存在的狀態,</span><span style="color:#6272a4">/// or prints an ERROR message if the state was not on the List. —— 或者,如果狀態不存在,則打印錯誤信息</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">DeleteState</span><span style="color:#999999">(</span>StateID id<span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>id <span style="color:#6272a4">==</span> StateID<span style="color:#999999">.</span>NullStateId<span style="color:#999999">)</span> <span style="color:#6272a4">// Check for NullState before deleting —— 判空</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSM ERROR: NullStateID is not allowed for a real state"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span>foreach <span style="color:#999999">(</span>FSMState state in states<span style="color:#999999">)</span> <span style="color:#6272a4">// Search the List and delete the state if it's inside it 搜索列表并刪除其中的狀態</span><span style="color:#999999">{</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>state<span style="color:#999999">.</span>ID <span style="color:#6272a4">==</span> id<span style="color:#999999">)</span><span style="color:#999999">{</span>states<span style="color:#999999">.</span><span style="color:#8be9fd">Remove</span><span style="color:#999999">(</span>state<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#999999">}</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSM ERROR: Impossible to delete state "</span> <span style="color:#6272a4">+</span> id<span style="color:#999999">.</span><span style="color:#8be9fd">ToString</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">+</span><span style="color:#f1fa8c">". It was not on the list of states"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// This method tries to change the state the FSM is in based on</span><span style="color:#6272a4">/// the current state and the transition passed. If current state</span><span style="color:#6272a4">/// doesn't have a target state for the transition passed, </span><span style="color:#6272a4">/// an ERROR message is printed.</span><span style="color:#6272a4">/// 該方法嘗試根據當前狀態和已通過的轉換改變FSM所處的狀態。如果當前狀態沒有傳遞的轉換的目標狀態,則輸出錯誤消息。</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">PerformTransition</span><span style="color:#999999">(</span>Transition trans<span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>trans <span style="color:#6272a4">==</span> Transition<span style="color:#999999">.</span>NullTransition<span style="color:#999999">)</span> <span style="color:#6272a4">// Check for NullTransition before changing the current state 在更改當前狀態之前檢查是否有NullTransition</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSM ERROR: NullTransition is not allowed for a real transition"</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span>StateID id <span style="color:#6272a4">=</span> currentState<span style="color:#999999">.</span><span style="color:#8be9fd">GetOutputState</span><span style="color:#999999">(</span>trans<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">// Check if the currentState has the transition passed as argument 檢查currentState是否將轉換作為參數傳遞</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>id <span style="color:#6272a4">==</span> StateID<span style="color:#999999">.</span>NullStateId<span style="color:#999999">)</span><span style="color:#999999">{</span>Debug<span style="color:#999999">.</span><span style="color:#8be9fd">LogError</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"FSM ERROR: State "</span> <span style="color:#6272a4">+</span> currentStateID<span style="color:#999999">.</span><span style="color:#8be9fd">ToString</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">+</span> <span style="color:#f1fa8c">" does not have a target state "</span> <span style="color:#6272a4">+</span><span style="color:#f1fa8c">" for transition "</span> <span style="color:#6272a4">+</span> trans<span style="color:#999999">.</span><span style="color:#8be9fd">ToString</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#ff79c6">return</span><span style="color:#999999">;</span><span style="color:#999999">}</span>currentStateID <span style="color:#6272a4">=</span> id<span style="color:#999999">;</span> <span style="color:#6272a4">// Update the currentStateID and currentState 更新當前狀態和ID</span>foreach <span style="color:#999999">(</span>FSMState state in states<span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#ff79c6">if</span> <span style="color:#999999">(</span>state<span style="color:#999999">.</span>ID <span style="color:#6272a4">==</span> currentStateID<span style="color:#999999">)</span><span style="color:#999999">{</span>currentState<span style="color:#999999">.</span><span style="color:#8be9fd">DoBeforeLeaving</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">// Do the post processing of the state before setting the new one 在設置新狀態之前是否對狀態進行后處理</span>currentState <span style="color:#6272a4">=</span> state<span style="color:#999999">;</span>currentState<span style="color:#999999">.</span><span style="color:#8be9fd">DoBeforeEntering</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">// Reset the state to its desired condition before it can reason or act 在它推動和動作之前,重置狀態到它所需的條件</span><span style="color:#ff79c6">break</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#999999">}</span><span style="color:#999999">}</span> <span style="color:#999999">}</span> </code></span>

4

Multimode?—— 多狀態



菜單狀態腳本:MenuState

游戲狀態腳本:GameState

我們來控制這兩個狀態,交由狀態機進行切換

菜單腳本

<span style="color:#000000"><code class="language-c"><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// 菜單狀態</span> <span style="color:#6272a4">/// </summary></span> public class MenuState <span style="color:#999999">:</span> FSMState <span style="color:#999999">{</span><span style="color:#ff79c6">void</span> <span style="color:#8be9fd">Awake</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>stateID <span style="color:#6272a4">=</span> StateID<span style="color:#999999">.</span>Menu<span style="color:#999999">;</span><span style="color:#8be9fd">AddTransition</span><span style="color:#999999">(</span>Transition<span style="color:#999999">.</span>Game<span style="color:#999999">,</span> StateID<span style="color:#999999">.</span>Game<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//(菜單狀態下:需要轉游戲)→→添加轉換,轉換游戲 —— 對應游戲狀態</span><span style="color:#6272a4">//map.Add(Transition.Game, StateID.Game);//上邊也可這么寫</span><span style="color:#999999">}</span><span style="color:#ff79c6">void</span> <span style="color:#8be9fd">Start</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>manager<span style="color:#999999">.</span>View<span style="color:#999999">.</span>StartButton<span style="color:#999999">.</span>onClick<span style="color:#999999">.</span><span style="color:#8be9fd">AddListener</span><span style="color:#999999">(</span>OnStarGameClick<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 開始游戲</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">OnStarGameClick</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>manager<span style="color:#999999">.</span>Fsm<span style="color:#999999">.</span><span style="color:#8be9fd">PerformTransition</span><span style="color:#999999">(</span>Transition<span style="color:#999999">.</span>Game<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 進入該狀態時</span><span style="color:#6272a4">/// </summary></span>public override <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">DoBeforeEntering</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>manager<span style="color:#999999">.</span>View<span style="color:#999999">.</span><span style="color:#8be9fd">ShowMenuUi</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 離開該狀態時</span><span style="color:#6272a4">/// </summary></span>public override <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">DoBeforeLeaving</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>manager<span style="color:#999999">.</span>View<span style="color:#999999">.</span><span style="color:#8be9fd">HideMenuUi</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span> <span style="color:#999999">}</span> </code></span>

游戲腳本

<span style="color:#000000"><code class="language-c"><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// 游戲狀態</span> <span style="color:#6272a4">/// </summary></span> public class GameState <span style="color:#999999">:</span> FSMState <span style="color:#999999">{</span><span style="color:#ff79c6">void</span> <span style="color:#8be9fd">Awake</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>stateID <span style="color:#6272a4">=</span> StateID<span style="color:#999999">.</span>Game<span style="color:#999999">;</span><span style="color:#8be9fd">AddTransition</span><span style="color:#999999">(</span>Transition<span style="color:#999999">.</span>Menu<span style="color:#999999">,</span> StateID<span style="color:#999999">.</span>Menu<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//(游戲狀態下:點擊暫停需要轉菜單)→→添加轉換,轉換菜單—— 對應菜單狀態</span><span style="color:#6272a4">//map.Add(Transition.Menu, StateID.Menu);//上邊也可這么寫</span><span style="color:#999999">}</span><span style="color:#ff79c6">void</span> <span style="color:#8be9fd">Start</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>manager<span style="color:#999999">.</span>View<span style="color:#999999">.</span>PauseButton<span style="color:#999999">.</span>onClick<span style="color:#999999">.</span><span style="color:#8be9fd">AddListener</span><span style="color:#999999">(</span>OnPauseButton<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 暫停</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">OnPauseButton</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>manager<span style="color:#999999">.</span>Fsm<span style="color:#999999">.</span><span style="color:#8be9fd">PerformTransition</span><span style="color:#999999">(</span>Transition<span style="color:#999999">.</span>Menu<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 進入該狀態時</span><span style="color:#6272a4">/// </summary></span>public override <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">DoBeforeEntering</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>manager<span style="color:#999999">.</span>View<span style="color:#999999">.</span><span style="color:#8be9fd">ShowGameUi</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 離開該狀態時</span><span style="color:#6272a4">/// </summary></span>public override <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">DoBeforeLeaving</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>manager<span style="color:#999999">.</span>View<span style="color:#999999">.</span><span style="color:#8be9fd">HideGameUi</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span> <span style="color:#999999">}</span> </code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

5

GameManager?——游戲總控腳本



游戲總控腳本:GameManager?—— 用來控制全局游戲邏輯 ?

我們在這個腳本中,將所有狀態批量添加到狀態機中

這里我通過修改,傳入了?GameManager?到所有狀態中

這樣我們后期可以在各個狀態中完成對?GameManager中函數的調用,同時節省了代碼,邏輯也非常清晰


游戲總控腳本

<span style="color:#000000"><code class="language-c">using UnityEngine<span style="color:#999999">;</span><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// 游戲總控腳本</span> <span style="color:#6272a4">/// </summary></span> public class GameManager <span style="color:#999999">:</span> MonoBehaviour <span style="color:#999999">{</span>public FSMSystem Fsm<span style="color:#999999">;</span> <span style="color:#6272a4">//有限狀態機系統對象</span>public View View<span style="color:#999999">;</span> <span style="color:#6272a4">// 顯示層</span>private <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">Awake</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>View <span style="color:#6272a4">=</span> GameObject<span style="color:#999999">.</span><span style="color:#8be9fd">FindGameObjectWithTag</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"View"</span><span style="color:#999999">)</span><span style="color:#999999">.</span>GetComponent<span style="color:#6272a4"><</span>View<span style="color:#6272a4">></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//這里要給 View 游戲對象設置標簽 "View"</span><span style="color:#6272a4">//添加所有狀態到狀態集(這里,我也通過修改,將 GameManager傳到所有狀態中,簡化代碼,便于調用)</span>Fsm <span style="color:#6272a4">=</span> new <span style="color:#8be9fd">FSMSystem</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//調用構造函數,內部會自動初始化 狀態集</span>FSMState<span style="color:#999999">[</span><span style="color:#999999">]</span> states <span style="color:#6272a4">=</span> GetComponentsInChildren<span style="color:#6272a4"><</span>FSMState<span style="color:#6272a4">></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//找到所有 狀態</span>foreach <span style="color:#999999">(</span>FSMState state in states<span style="color:#999999">)</span><span style="color:#999999">{</span>Fsm<span style="color:#999999">.</span><span style="color:#8be9fd">AddState</span><span style="color:#999999">(</span>state<span style="color:#999999">,</span> this<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//將狀態,逐個添加到 狀態機中</span><span style="color:#999999">}</span>MenuState menuState <span style="color:#6272a4">=</span> GetComponentInChildren<span style="color:#6272a4"><</span>MenuState<span style="color:#6272a4">></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>Fsm<span style="color:#999999">.</span><span style="color:#8be9fd">SetCurrentState</span><span style="color:#999999">(</span>menuState<span style="color:#999999">)</span><span style="color:#999999">;</span> <span style="color:#6272a4">//默認狀態是 菜單狀態</span><span style="color:#999999">}</span> <span style="color:#999999">}</span> </code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

6

View?—— 視圖腳本



用?View?腳本來對我們所有?UI?元素進行賦值與管理

項目中引用了?DoTween?插件,來完成對UI簡單動畫的控制

視圖腳本

<span style="color:#000000"><code class="language-c">using DG<span style="color:#999999">.</span>Tweening<span style="color:#999999">;</span> using UnityEngine<span style="color:#999999">;</span> using UnityEngine<span style="color:#999999">.</span>UI<span style="color:#999999">;</span><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// 視圖腳本 —— 管理UI元素</span> <span style="color:#6272a4">/// </summary></span> public class View <span style="color:#999999">:</span> MonoBehaviour <span style="color:#999999">{</span>private RectTransform menuUi<span style="color:#999999">;</span> <span style="color:#6272a4">//菜單頁</span>private RectTransform gameUi<span style="color:#999999">;</span> <span style="color:#6272a4">//游戲頁</span>public Button StartButton<span style="color:#999999">;</span> <span style="color:#6272a4">//開始按鈕</span>public Button PauseButton<span style="color:#999999">;</span> <span style="color:#6272a4">//暫停按鈕</span>public Ease PubEase<span style="color:#999999">;</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 初始化函數</span><span style="color:#6272a4">/// </summary></span><span style="color:#ff79c6">void</span> <span style="color:#8be9fd">Awake</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>menuUi <span style="color:#6272a4">=</span> <span style="color:#999999">(</span>RectTransform<span style="color:#999999">)</span> <span style="color:#8be9fd">Find</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"Menu Ui"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>gameUi <span style="color:#6272a4">=</span> <span style="color:#999999">(</span>RectTransform<span style="color:#999999">)</span> <span style="color:#8be9fd">Find</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"Game Ui"</span><span style="color:#999999">)</span><span style="color:#999999">;</span>StartButton <span style="color:#6272a4">=</span> <span style="color:#8be9fd">Find</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"Menu Ui/Menu Button"</span><span style="color:#999999">)</span><span style="color:#999999">.</span>GetComponent<span style="color:#6272a4"><</span>Button<span style="color:#6272a4">></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span>PauseButton <span style="color:#6272a4">=</span> <span style="color:#8be9fd">Find</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"Game Ui/Pause Button"</span><span style="color:#999999">)</span><span style="color:#999999">.</span>GetComponent<span style="color:#6272a4"><</span>Button<span style="color:#6272a4">></span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 顯示菜單頁</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">ShowMenuUi</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>menuUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOScale</span><span style="color:#999999">(</span>new <span style="color:#8be9fd">Vector3</span><span style="color:#999999">(</span><span style="color:#f1fa8c">0.3f</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.1f</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">OnComplete</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">=</span><span style="color:#6272a4">></span><span style="color:#999999">{</span>menuUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOScale</span><span style="color:#999999">(</span>Vector3<span style="color:#999999">.</span>one<span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">;</span>StartButton<span style="color:#999999">.</span>enabled <span style="color:#6272a4">=</span> true<span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">SetEase</span><span style="color:#999999">(</span>PubEase<span style="color:#999999">)</span><span style="color:#999999">;</span>menuUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOAnchorPos</span><span style="color:#999999">(</span>Vector2<span style="color:#999999">.</span>zero<span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">SetEase</span><span style="color:#999999">(</span>PubEase<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 隱藏菜單頁</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">HideMenuUi</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>menuUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOScale</span><span style="color:#999999">(</span>new <span style="color:#8be9fd">Vector3</span><span style="color:#999999">(</span><span style="color:#f1fa8c">0.3f</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.1f</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">OnComplete</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">=</span><span style="color:#6272a4">></span><span style="color:#999999">{</span>menuUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOAnchorPos</span><span style="color:#999999">(</span>new <span style="color:#8be9fd">Vector2</span><span style="color:#999999">(</span><span style="color:#6272a4">-</span><span style="color:#f1fa8c">600</span><span style="color:#999999">,</span> <span style="color:#6272a4">-</span><span style="color:#f1fa8c">450</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">;</span>menuUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOScale</span><span style="color:#999999">(</span>Vector3<span style="color:#999999">.</span>zero<span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">OnComplete</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">=</span><span style="color:#6272a4">></span> <span style="color:#999999">{</span> StartButton<span style="color:#999999">.</span>enabled <span style="color:#6272a4">=</span> false<span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">SetEase</span><span style="color:#999999">(</span>PubEase<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">SetEase</span><span style="color:#999999">(</span>PubEase<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 顯示游戲頁</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">ShowGameUi</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>gameUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOScale</span><span style="color:#999999">(</span>new <span style="color:#8be9fd">Vector3</span><span style="color:#999999">(</span><span style="color:#f1fa8c">0.3f</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.1f</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">OnComplete</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">=</span><span style="color:#6272a4">></span><span style="color:#999999">{</span>gameUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOScale</span><span style="color:#999999">(</span>Vector3<span style="color:#999999">.</span>one<span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">;</span>PauseButton<span style="color:#999999">.</span>enabled <span style="color:#6272a4">=</span> true<span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">SetEase</span><span style="color:#999999">(</span>PubEase<span style="color:#999999">)</span><span style="color:#999999">;</span>gameUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOAnchorPos</span><span style="color:#999999">(</span>Vector2<span style="color:#999999">.</span>zero<span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">SetEase</span><span style="color:#999999">(</span>PubEase<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 隱藏游戲頁</span><span style="color:#6272a4">/// </summary></span>public <span style="color:#ff79c6">void</span> <span style="color:#8be9fd">HideGameUi</span><span style="color:#999999">(</span><span style="color:#999999">)</span><span style="color:#999999">{</span>gameUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOScale</span><span style="color:#999999">(</span>new <span style="color:#8be9fd">Vector3</span><span style="color:#999999">(</span><span style="color:#f1fa8c">0.3f</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.1f</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">OnComplete</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">=</span><span style="color:#6272a4">></span><span style="color:#999999">{</span>gameUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOAnchorPos</span><span style="color:#999999">(</span>new <span style="color:#8be9fd">Vector2</span><span style="color:#999999">(</span><span style="color:#6272a4">-</span><span style="color:#f1fa8c">600</span><span style="color:#999999">,</span> <span style="color:#6272a4">-</span><span style="color:#f1fa8c">450</span><span style="color:#999999">)</span><span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">;</span>gameUi<span style="color:#999999">.</span><span style="color:#8be9fd">DOScale</span><span style="color:#999999">(</span>Vector3<span style="color:#999999">.</span>zero<span style="color:#999999">,</span> <span style="color:#f1fa8c">0.3f</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">OnComplete</span><span style="color:#999999">(</span><span style="color:#999999">(</span><span style="color:#999999">)</span> <span style="color:#6272a4">=</span><span style="color:#6272a4">></span> <span style="color:#999999">{</span> PauseButton<span style="color:#999999">.</span>enabled <span style="color:#6272a4">=</span> false<span style="color:#999999">;</span> <span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">SetEase</span><span style="color:#999999">(</span>PubEase<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#999999">)</span><span style="color:#999999">.</span><span style="color:#8be9fd">SetEase</span><span style="color:#999999">(</span>PubEase<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// 查找對Ui元素完成賦值</span><span style="color:#6272a4">/// </summary></span><span style="color:#6272a4">/// <param name="uiElement">Ui名查找路徑</param></span>Transform <span style="color:#8be9fd">Find</span><span style="color:#999999">(</span>string uiElement<span style="color:#999999">)</span><span style="color:#999999">{</span><span style="color:#ff79c6">return</span> transform<span style="color:#999999">.</span><span style="color:#8be9fd">Find</span><span style="color:#999999">(</span><span style="color:#f1fa8c">"Canvas/"</span> <span style="color:#6272a4">+</span> uiElement<span style="color:#999999">)</span><span style="color:#999999">;</span><span style="color:#999999">}</span> <span style="color:#999999">}</span> </code></span>

7

Final effect?—— 最終效果



我們通過狀態機簡單的完成了 開始游戲 和暫停的狀態切換

代碼中注釋寫的非常詳細了,請初學者認真看下

具體流程就是:

1.?GameManager?完成將所有子類狀態添加到狀態集中

2.?View?獲取到我們所需要的所有?UI?元素對象,并提供公有方法可供各個狀態訪問

3. 確認好各個狀態的進入 與離開時機發生時,需要執行的事件,并交由狀態機去管理!

狀態進入:DoBeforeEntering()
狀態離開:DoBeforeLeaving()

4.?例子較為簡單,為了方便初學者理解學習只寫了2個狀態

根據需求,大家可以舉一反三,多寫幾個狀態練習一下,其實流程很簡單!


8

Project?—— 項目文件



項目文件為?unitypackage?文件包:

下載導入?Unity?即可使用

點擊下載 —— 項目資源?(積分支持)

點擊下載 —— 項目資源?(Chinar免費)

最終效果: (由于GIF錄制 60幀數的限制,所以我點擊太快了,看著有些卡似得)

?

至此:狀態機教程結束

?


支持

May Be?—— 搞開發,總有一天要做的事!

?

擁有自己的服務器,無需再找攻略!

Chinar?提供一站式教程,閉眼式創建!

為新手節省寶貴時間,避免采坑!

?

先點擊領取 —— 阿里全產品優惠券?(享受最低優惠)


?

1 ——?云服務器超全購買流程?(新手必備!)


2 ——?阿里ECS云服務器自定義配置 - 購買教程(新手必備!)


3——?Windows 服務器配置、運行、建站一條龍 !


4 ——?Linux 服務器配置、運行、建站一條龍 !


?

?

技術交流群:806091680 !?Chinar?歡迎你的加入

?


END

本博客為非營利性個人原創,除部分有明確署名的作品外,所刊登的所有作品的著作權均為本人所擁有,本人保留所有法定權利。違者必究

對于需要復制、轉載、鏈接和傳播博客文章或內容的,請及時和本博主進行聯系,留言,Email: ichinar@icloud.com

對于經本博主明確授權和許可使用文章及內容的,使用時請注明文章或內容出處并注明網址

總結

以上是生活随笔為你收集整理的【转】有限状态机用法教程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。