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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

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

?

有限狀態(tài)機(jī)用法教程

?

文章目錄

  • 有限狀態(tài)機(jī)用法教程

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

?

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

?


1

Finite-state machine?—— 有限狀態(tài)機(jī)



有限狀態(tài)機(jī)簡稱:?FSM?—— 簡稱狀態(tài)機(jī)

是表示有限個(gè)狀態(tài)以及在這些狀態(tài)之間的轉(zhuǎn)移和動(dòng)作等行為的數(shù)學(xué)模型


其他的不多說,對于我們開發(fā)者來說,狀態(tài)機(jī)可以在全局視角下,管理我們的游戲狀態(tài)/人物狀態(tài)

使我們的工程邏輯清晰,將游戲/項(xiàng)目各個(gè)狀態(tài)的轉(zhuǎn)換,交由狀態(tài)機(jī)統(tǒng)一管理

極大的避免了當(dāng)狀態(tài)過多 / 轉(zhuǎn)換狀態(tài)過多時(shí),每次都需要調(diào)用相應(yīng)函數(shù)來完成轉(zhuǎn)換的麻煩


對于初學(xué)者來講,套用狀態(tài)機(jī)來對狀態(tài)進(jìn)行管理,可能認(rèn)為過于麻煩

其實(shí)不用怕,那只是因?yàn)椴皇煜び梅ê瓦壿嬃鞒虒?dǎo)致的

熟練的運(yùn)用狀態(tài)機(jī)來管理我們的項(xiàng)目狀態(tài),是很有必要的

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


2

Foreword?—— 前言()



網(wǎng)上的大神們?yōu)榱烁娴年U述狀態(tài)機(jī)的具體工作方式,他們有些說的極為詳細(xì)

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

例如:(圖片引用自網(wǎng)絡(luò)大神博客)

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

Chinar?會通過一些簡單的例子,來帶領(lǐng)初學(xué)者了解并學(xué)會如何使用狀態(tài)機(jī)來管理我們的工程.

師傅領(lǐng)進(jìn)門,修行靠個(gè)人 ,一切都需要先入門后,自己再慢慢擴(kuò)展,不然一切都是扯淡


3

Example?—— 示例



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

這里?Chinar?用一個(gè)簡單的游戲狀態(tài)切換邏輯來說明狀態(tài)機(jī)用法

MVC?設(shè)計(jì)模式


FSM?一共2個(gè)類,不需要掛載到游戲?qū)ο笊?/strong>

FSMState?狀態(tài)父類,所有子類狀態(tài)都繼承于這個(gè)類

例如以下工程:我們要需要2個(gè)狀態(tài):?菜單狀態(tài) 與 游戲狀態(tài)

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



狀態(tài)機(jī)腳本

<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. —— 在此枚舉中放置轉(zhuǎn)換的標(biāo)簽。</span> <span style="color:#6272a4">/// Don't change the first label, NullTransition as FSMSystem class uses it. —— 不要改變第一個(gè)標(biāo)簽:NullTransition,因?yàn)镕SMSystem類使用它。</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 —— 使用此轉(zhuǎn)換表示系統(tǒng)中不存在的轉(zhuǎn)換</span>Game<span style="color:#999999">,</span> <span style="color:#6272a4">//轉(zhuǎn)到游戲</span>Menu <span style="color:#6272a4">//轉(zhuǎn)到菜單</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. —— 在此枚舉中放置狀態(tài)的標(biāo)簽。</span> <span style="color:#6272a4">/// Don't change the first label, NullStateID as FSMSystem class uses it.不要改變第一個(gè)標(biāo)簽:NullStateID,因?yàn)镕SMSystem類使用它。</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表示系統(tǒng)中不存在的狀態(tài)</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.該類表示有限狀態(tài)系統(tǒng)中的狀態(tài)。</span> <span style="color:#6272a4">/// Each state has a Dictionary with pairs (transition-state) showing 每個(gè)狀態(tài)都有一個(gè)對顯示(轉(zhuǎn)換狀態(tài))的字典</span> <span style="color:#6272a4">/// which state the FSM should be if a transition is fired while this state is the current state.如果在此狀態(tài)為當(dāng)前狀態(tài)時(shí)觸發(fā)轉(zhuǎn)換,則FSM應(yīng)處于那種狀態(tài)。</span> <span style="color:#6272a4">/// Method Reason is used to determine which transition should be fired .方法原因用于確定應(yīng)觸發(fā)哪個(gè)轉(zhuǎn)換。</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.方法具有執(zhí)行NPC動(dòng)作的代碼應(yīng)該在這種狀態(tài)下執(zhí)行。</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">//字典 《轉(zhuǎn)換,狀態(tài)ID》</span>protected StateID stateID<span style="color:#999999">;</span> <span style="color:#6272a4">//私有ID</span>public StateID ID <span style="color:#6272a4">//狀態(tài)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">//保證子類狀態(tài)可以訪問到總控 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">/// 添加轉(zhuǎn)換</span><span style="color:#6272a4">/// </summary></span><span style="color:#6272a4">/// <param name="trans">轉(zhuǎn)換狀態(tài)</param></span><span style="color:#6272a4">/// <param name="id">轉(zhuǎn)換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 —— //檢查是否有參數(shù)無效</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 —— 因?yàn)檫@是一個(gè)確定性FSM,檢查當(dāng)前的轉(zhuǎn)換是否已經(jīng)在字典中</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. —— 該方法從狀態(tài)映射中刪除一對轉(zhuǎn)換狀態(tài)。</span><span style="color:#6272a4">/// If the transition was not inside the state's map, an ERROR message is printed. —— 如果轉(zhuǎn)換不在狀態(tài)映射內(nèi),則會打印一條錯(cuò)誤消息。</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 —— 檢查狀態(tài)是否為空</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—— 如果該狀態(tài)接收到轉(zhuǎn)換,該方法返回FSM應(yīng)該為新狀態(tài)</span><span style="color:#6272a4">/// 得到輸出狀態(tài)</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 —— 檢查字典中是否有這個(gè)狀態(tài)</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. —— 該方法用于在進(jìn)入狀態(tài)條件之前設(shè)置狀態(tài)條件。</span><span style="color:#6272a4">/// It is called automatically by the FSMSystem class before assigning it to the current state.—— 在分配它之前,FSMSystem類會自動(dòng)調(diào)用它到當(dāng)前狀態(tài)</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更改為另一個(gè)變量之前進(jìn)行任何必要的修改。在切換到新狀態(tài)之前,FSMSystem會自動(dòng)調(diào)用它。</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">/// 這個(gè)方法決定狀態(tài)是否應(yīng)該轉(zhuǎn)換到它列表上的另一個(gè)NPC是對這個(gè)類控制的對象的引用</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做的每一個(gè)動(dòng)作、動(dòng)作或交流都應(yīng)該放在這里</span><span style="color:#6272a4">/// NPC是這個(gè)類控制的對象的引用</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類表示有限狀態(tài)機(jī)類。</span> <span style="color:#6272a4">/// It has a List with the States the NPC has and methods to add, 它句有一個(gè)狀態(tài)列表,NPC有添加、刪除狀態(tài)和更改機(jī)器當(dāng)前狀態(tài)的方法。</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">//狀態(tài)集</span><span style="color:#6272a4">// The only way one can change the state of the FSM is by performing a transition 改變FSM狀態(tài)的唯一方法是進(jìn)行轉(zhuǎn)換</span><span style="color:#6272a4">// Don't change the CurrentState directly 不要直接改變當(dāng)前狀態(tài)</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">/// 默認(rèn)構(gòu)造函數(shù)</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">/// 設(shè)置當(dāng)前狀態(tài)</span><span style="color:#6272a4">/// </summary></span><span style="color:#6272a4">/// <param name="state">初始狀態(tài)</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">//開始前狀態(tài)切換</span><span style="color:#999999">}</span><span style="color:#6272a4">/// <summary></span><span style="color:#6272a4">/// This method places new states inside the FSM, —— 這個(gè)方法在FSM內(nèi)部放置一個(gè)放置一個(gè)新狀態(tài)</span><span style="color:#6272a4">/// or prints an ERROR message if the state was already inside the List. —— 或者,如果狀態(tài)已經(jīng)在列表中,則打印錯(cuò)誤消息。</span><span style="color:#6272a4">/// First state added is also the initial state. 第一個(gè)添加的狀態(tài)也是初始狀態(tài)。</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, —— 插入的第一個(gè)狀態(tài)也是初始狀態(tài),// the state the machine is in when the simulation begins —— 狀態(tài)機(jī)是在模擬開始時(shí)</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">//給每個(gè)狀態(tài)添加總控 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 如果狀態(tài)不在列表中,則將其添加到列表中 (添加狀態(tài)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, —— 這個(gè)方法從FSM列表中刪除一個(gè)存在的狀態(tài),</span><span style="color:#6272a4">/// or prints an ERROR message if the state was not on the List. —— 或者,如果狀態(tài)不存在,則打印錯(cuò)誤信息</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 搜索列表并刪除其中的狀態(tài)</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">/// 該方法嘗試根據(jù)當(dāng)前狀態(tài)和已通過的轉(zhuǎn)換改變FSM所處的狀態(tài)。如果當(dāng)前狀態(tài)沒有傳遞的轉(zhuǎn)換的目標(biāo)狀態(tài),則輸出錯(cuò)誤消息。</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 在更改當(dāng)前狀態(tài)之前檢查是否有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是否將轉(zhuǎn)換作為參數(shù)傳遞</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 更新當(dāng)前狀態(tài)和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 在設(shè)置新狀態(tài)之前是否對狀態(tài)進(jìn)行后處理</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 在它推動(dòng)和動(dòng)作之前,重置狀態(tài)到它所需的條件</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?—— 多狀態(tài)



菜單狀態(tài)腳本:MenuState

游戲狀態(tài)腳本:GameState

我們來控制這兩個(gè)狀態(tài),交由狀態(tài)機(jī)進(jìn)行切換

菜單腳本

<span style="color:#000000"><code class="language-c"><span style="color:#6272a4">/// <summary></span> <span style="color:#6272a4">/// 菜單狀態(tài)</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">//(菜單狀態(tài)下:需要轉(zhuǎn)游戲)→→添加轉(zhuǎn)換,轉(zhuǎn)換游戲 —— 對應(yīng)游戲狀態(tài)</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">/// 進(jìn)入該狀態(tài)時(shí)</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">/// 離開該狀態(tài)時(shí)</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">/// 游戲狀態(tài)</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">//(游戲狀態(tài)下:點(diǎn)擊暫停需要轉(zhuǎn)菜單)→→添加轉(zhuǎn)換,轉(zhuǎn)換菜單—— 對應(yīng)菜單狀態(tài)</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">/// 進(jìn)入該狀態(tài)時(shí)</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">/// 離開該狀態(tài)時(shí)</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?—— 用來控制全局游戲邏輯 ?

我們在這個(gè)腳本中,將所有狀態(tài)批量添加到狀態(tài)機(jī)中

這里我通過修改,傳入了?GameManager?到所有狀態(tài)中

這樣我們后期可以在各個(gè)狀態(tài)中完成對?GameManager中函數(shù)的調(diào)用,同時(shí)節(jié)省了代碼,邏輯也非常清晰


游戲總控腳本

<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">//有限狀態(tài)機(jī)系統(tǒng)對象</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 游戲?qū)ο笤O(shè)置標(biāo)簽 "View"</span><span style="color:#6272a4">//添加所有狀態(tài)到狀態(tài)集(這里,我也通過修改,將 GameManager傳到所有狀態(tài)中,簡化代碼,便于調(diào)用)</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">//調(diào)用構(gòu)造函數(shù),內(nèi)部會自動(dòng)初始化 狀態(tài)集</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">//找到所有 狀態(tài)</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">//將狀態(tài),逐個(gè)添加到 狀態(tài)機(jī)中</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">//默認(rèn)狀態(tài)是 菜單狀態(tài)</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?元素進(jìn)行賦值與管理

項(xiàng)目中引用了?DoTween?插件,來完成對UI簡單動(dòng)畫的控制

視圖腳本

<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">/// 初始化函數(shù)</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?—— 最終效果



我們通過狀態(tài)機(jī)簡單的完成了 開始游戲 和暫停的狀態(tài)切換

代碼中注釋寫的非常詳細(xì)了,請初學(xué)者認(rèn)真看下

具體流程就是:

1.?GameManager?完成將所有子類狀態(tài)添加到狀態(tài)集中

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

3. 確認(rèn)好各個(gè)狀態(tài)的進(jìn)入 與離開時(shí)機(jī)發(fā)生時(shí),需要執(zhí)行的事件,并交由狀態(tài)機(jī)去管理!

狀態(tài)進(jìn)入:DoBeforeEntering()
狀態(tài)離開:DoBeforeLeaving()

4.?例子較為簡單,為了方便初學(xué)者理解學(xué)習(xí)只寫了2個(gè)狀態(tài)

根據(jù)需求,大家可以舉一反三,多寫幾個(gè)狀態(tài)練習(xí)一下,其實(shí)流程很簡單!


8

Project?—— 項(xiàng)目文件



項(xiàng)目文件為?unitypackage?文件包:

下載導(dǎo)入?Unity?即可使用

點(diǎn)擊下載 —— 項(xiàng)目資源?(積分支持)

點(diǎn)擊下載 —— 項(xiàng)目資源?(Chinar免費(fèi))

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

?

至此:狀態(tài)機(jī)教程結(jié)束

?


支持

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

?

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

Chinar?提供一站式教程,閉眼式創(chuàng)建!

為新手節(jié)省寶貴時(shí)間,避免采坑!

?

先點(diǎn)擊領(lǐng)取 —— 阿里全產(chǎn)品優(yōu)惠券?(享受最低優(yōu)惠)


?

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


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


3——?Windows 服務(wù)器配置、運(yùn)行、建站一條龍 !


4 ——?Linux 服務(wù)器配置、運(yùn)行、建站一條龍 !


?

?

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

?


END

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

對于需要復(fù)制、轉(zhuǎn)載、鏈接和傳播博客文章或內(nèi)容的,請及時(shí)和本博主進(jìn)行聯(lián)系,留言,Email: ichinar@icloud.com

對于經(jīng)本博主明確授權(quán)和許可使用文章及內(nèi)容的,使用時(shí)請注明文章或內(nèi)容出處并注明網(wǎng)址

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。