前言
勘誤
- IActor類別一開始是定義為Interface,只是後來要做XML解析時發現不支援介面型態,只好改成class,這種「想把它當介面使用,但礙於情況只能定義為類別」的時候,命名規則會是依照實際型態(class)還是意圖(interface)呢?
上一篇我介面名稱為IActor其實是不太正確的,應該說一開始改名成IActor的動機是不對的。這種想要透過環境規定限制修改行為的稱為"Contract",是程式在規劃時要做好的管理。滿有趣的是,在[1]討論中看來Contract Class似乎也是可以以介面命名(?)。
原本用partial class 是想說未來可能有的dll的類別需要傳遞額外的資料,這樣僅須在該類別附加定義就好,但實際上跨dll的partial class是不能合併的[3]。在討論[2]中得出,partial class主要是用在自動產生的程式上。
之後也許可以抽空了解更多軟體工程的詳細,以前還沒實做時覺得都是紙上談兵,現在犯錯後才能慢慢學習。
回顧,基本函數呼叫
上一篇只有簡單講到如何呼叫指定名稱的dll與方法,但實際上是不能寫死的,這回要談的是「如何在XML裡面指定觸發條件」。
上一篇的架構圖:
*備註,以下部分程式碼為早期開發紀錄,實際以Github為主。
前置:XML實體宣告
由於有些值會一直重複出現(例如路徑),可以在一開頭宣告ENTITY物件,使用時只需 &變數;
使用範例:
前置:引入xsd檔
在XML開頭引入即可。
Update掛載
首先用List型態紀錄各種觸發條件的資料,由trigger字串觸發的Event用字典型態將觸發紀錄<觸發訊息 , 方法>。
在讀取XML時加入:
在XML裡面定義一個「UPDATE時 呼叫TestDll下面的ActionDll.ForDebug類別的Prt方法,傳入參數為<para>標籤的內容。」
結果:
Input掛載與回傳
這邊是搭配舊版Unity InputSystem,須在InputManager那邊加入自定義Axies。
上面的程式是直接將Axies觸發的值裝在第一個參數回傳,因此我在XML多定義一個trig變數裝傳入值。
結果:
當我按下左右鍵的時候,可以看到餐數有變動。
冷卻機制
由於這個腳本工具的目標是「通用RPG動作管理」,所以怎麼能少了技能冷卻設定呢?
範例: 玩家每間隔1.2秒才能跳躍,且跳躍觸發為InputSystem的"Vertical"。
用字典管理方法與對應冷卻結束時間:
Event設計
當初在想Event呼叫流程要怎麼個設計才好,我想到以下兩個方案:
最後選擇方法1,因為方法2無法傳遞資料 (如傷害數值…)。
在Contract類別(原介面)多宣告Event變數,這邊分為本地與Global事件兩種。
Unity端負責呼叫
觸發 (Global)
範例:玩家觸發攻擊方法,怪物接收傷害。
由於這是外部的dll方法,無法使用Unity專案內自己宣告的腳本,因此只能用比較原始的Tag比較等。
攻擊的XML
接收 (Global)
此為怪物的Dll內定義的受傷的方法。
XML定義
觸發、接收 (Local)
怪物可能在遊戲內自己受傷(例如撞到中立的尖刺物件),則是由Unity端的邏輯觸發Hurt方法,可使用Local的Event如下:
最後透過Global與Local事件,達成了有來有往的呼叫架構。
[範例]做個Ground Check
由於跳躍光是用冷卻時間限制還不夠完善,需要搭配Ground Check來檢查玩家是否站在地面上。
Dll 內容:
XML: