透過.MADSTATE檔案結合模型動畫(Mesh Animation)與遊戲事件

.madState函式名稱介紹
範例
可用的函式
互斥(exclusive)與互相包含(inclusive)的狀態

透過.MADSTATE檔案結合模型動畫(Mesh Animation)與遊戲事件

此份文件描述了.madState檔案的格式與用途。.madState檔案提供將儲存在.mad檔案中的模型動畫綁定給特定遊戲中事件的方法。.madState檔案是lua script,其中包含了一些在特定遊戲事件中會被執行的函式。例如你可以利用這個系統來將某個動畫指定給船隻離開港口的事件。每次遊戲中發生特定事件時都會呼叫對應的函式。因此,他們應該很單純。

這些函式會在SobWithMesh的MadState類別中被呼叫。MadState類別是一些被封裝起來的布林值狀態變數。當某個狀態變數的狀態被改變,將會呼叫.madstate中對應的函式(如果有的話)。

Mesh animations are deterministic in playback. Therefore, it is permissible to make the MadState dependent upon mesh animations and the game simulation dependent upon the MadState. This is one way to enable mesh animation to fit in with procedural animation. For example, we can require a ship to deploy its weapons (a mesh animation) before training them on targets (procedural animation).

.madState函式名稱介紹

.madState檔案中的函式名稱看起來像這樣:

<ShipName>_<State>_On<Event>

其中:

<ShipName>是船艦的名稱,例如 VGR_HEAVYMISSILEFRIGATE。

<State>則是狀態變數。例如 Launching

下面是狀態表:

狀態名稱 用途
Normal 當船艦在遊戲中被創造時呼叫
Open 當船艦被「開啟(Open)」或被「施放」(譯注:如施放維格探測器)時呼叫。
Closed 船艦不再處於「開啟(Open)」或被「施放」
CodeRed 當船艦嘗試發射武器時被呼叫(譯注:如開啟飛彈護衛艦的飛彈艙門)
CodeGreen 當船艦不再發射武器時被呼叫(呼叫前會有一小段時間延遲)
ResourceStart 船艦準備開始採集資源。當船艦正要進入資源採集位置時被呼叫
ResourceDo 船艦已經鎖定在資源採集點上,正在採集資源
ResourceEnd 船艦離開資源採集點
RepairStart 船艦正要進入修理其他單位的定點時被呼叫
RepairDo 船艦鎖定在修理點上,正在進行修理動作
RepairEnd 完成維修的動作
DockPathOpen 進入有連結動畫的停泊路徑(animation linked dock path,在hod檔案中設定)。要停靠或發射的船艦會等待這個狀態被設定。
DockPathClosed 離開有連結動畫的停泊路徑
Launched 船隻已完成發射離港的動作
Docked 船隻正在進行停泊的最後動作
DefenseFieldActivate 嘗試啟動防禦場。遊戲指令在這個狀態被設定前不會被啟動(譯著:我看不懂第二句話的意思...)
DefenseFieldDeActivate 解除防禦場
CloakFieldActivate 嘗試啟動隱形狀態
CloakFieldDeactivate 解除隱形狀態
HyperspaceGateActivate 超空間門就定位,正在進行超空間門的連結
HyperspaceGateDeActivate 超空間門的連結被解除
DoingFlightManeuver 船艦正在進行飛行動作(譯注:應該是指攻擊時的飛行動作,在「addAbility ( NewShipType , " CanAttack "...」中設定)
CaptureActive 船艦開始捕捉其他單位
CaptureInActive 船艦停止捕捉其他單位
NIS00 由NIS動畫呼叫
NIS01 由NIS動畫呼叫
NIS02 由NIS動畫呼叫

事件(event)則有下列幾種:

事件 用途
OnSet 當遊戲觸發特定的狀態時會被呼叫
OnPause 當狀態相關的動畫被暫停時會被呼叫
OnEnd 當狀態相關的動畫停止時會被呼叫

範例:

這裡有個.madState腳本的範例:

VGR_HEAVYMISSILEFRIGATE_CodeRed_OnSet = function(ship) 
    setState(ship, "CodeRed", 0) 
    startAnim(ship, "Open") 
    startEffect(ship, "Open") 
    setPauseTime(ship, "Open", 1000) 
end 
 
VGR_HEAVYMISSILEFRIGATE_CodeRed_OnPause = function(ship) 
    setState(ship, "CodeRed", 1) 
end 

VGR_HEAVYMISSILEFRIGATE_CodeGreen_OnSet = function(ship) 
    startAnim(ship, "Close") 
    startEffect(ship, "Close") 
    setTime(ship,"Close",0) 
    setPauseTime(ship, "Close", 1000) 
end 

很明顯的,這是給維格重型飛彈護衛艦使用的script。其中定義了進入「Code Red」以及「Code Green」狀態的動畫。當進入Code Red時,開啟飛彈艙門的動畫會被啟動,並且在動畫結束時暫停動作(這裡使用的時間長度為1000秒,理由只是因為這個數字夠大)。按照預設,系統在呼叫script的同時也會設定狀態變數,所以我們這裡必須先取消Code Red,避免武器在動畫完成前就發射。在OnPause函式中我們再手動設定Code Red狀態為啟動。當進入「Code Green」狀態時,關閉飛彈艙門的動畫被啟動,同時「Code Green」狀態也會被呼叫這段函式的程式碼所設定。

可用的函式:

在事件函式中,你可以呼叫任何可以使用的Lua函式。然而我們也定義了一些動畫╱狀態相關的函式:

setState(ship, stateName, state)

設定船艦的MADState類別中所儲存的狀態。這個函式不會觸發對應的_OnSet函式。這在 making the setting of a state dependent upon an animation completing, or reaching a pause point 時特別有用

ship sob* 由遊戲傳入
stateName 字串 狀態的名稱,詳見上列的狀態表
state 布林值(0或1) 狀態被啟動╱關閉
回傳值  

getState(ship, stateName)

查詢船艦的MADstate類別中特定狀態的值

ship sob* 由遊戲傳入
stateName 字串 狀態的名稱,詳見上列的狀態表
回傳值 布林值(0或1) 狀態被啟動╱關閉

startAnim(ship, animName)

啟動指定的模型動畫。正在執行的動畫不會被重新啟動。如果指定的動畫沒有被找到將會產生一個assert。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
回傳值  

startParamAnim(ship, animName, param)

啟動包含參數的模型動畫(parameterized mesh animation)。 包含參數的模型動畫的時間由一個額外傳入的參數決定,參數的範圍0到1。正在執行的動畫不會被重新啟動。如果指定的動畫沒有被找到將會產生一個assert。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
param 字串

變數的名稱。

「HorizontalRotation」與「VerticalRotation」是內建的動畫,依照船艦的旋轉推進器來決定船隻的旋轉,類似引擎的火光加入參數的方法。

回傳值  

stopAnim(ship, animName)

停止模型動畫。被指定的動畫不需要處於執行中的狀態。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
回傳值  

pauseAnim(ship, animName)

暫時停止模型動畫。被指定的動畫不需要處於執行中的狀態。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
回傳值  

unpauseAnim(ship, animName)

繼續播放被暫停的模型動畫。被指定的動畫不需要處於執行中或是暫停中的狀態。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
回傳值  

setPauseTime(ship, animName, time)

將指定的動畫暫停一段時間。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
time 浮點數

動畫會暫停的時間長度,單位是秒。Pass a very large number to pause at the end.

回傳值  

getPauseTime(ship, animName)

查詢特定動畫的暫停時間。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
回傳值 浮點數

動畫會暫停的時間長度,單位是秒。Pass a very large number to pause at the end.


setTime(ship, animName, time)

設定動畫要跳躍到哪個時間點(FF或Rew)

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
time 浮點數

動畫要跳躍到哪個時間點,單位是秒。超過動畫播放時間會被定在動畫的結束點。

回傳值  

getTime(ship, animName)

查詢動畫目前的時間點。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
回傳值 浮點數

動畫目前的時間點,單位是秒。


setLoopCount(ship, animName, nLoops)

設定動畫要重複播放的次數。預設為0

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
nLoops 整數

動畫要複播放的次數

回傳值  

getLoopCount(ship, animName)

設定動畫會重複播放的次數。

ship sob* 由遊戲傳入
animName 字串 .mad中儲存的動畫名稱
回傳值 整數

動畫要複播放的次數。不會重複播放的動畫會回傳0


startEffect(ship, eventName)

啟動船艦.event檔案中所指定的特效事件。

ship sob* 由遊戲傳入
eventName 字串 要播放的特效名稱
回傳值 Effect handle

被啟動的特效的handle

互斥(exclusive)與互相包含(inclusive)的狀態

狀態可以是互斥的或是互相包含的。這讓某些動畫的行為更容易被使用在船艦上。在Scripts/MeshAnimation.lua文件中,包含了名為inclusive(互相包含)與exclusive(互斥)的表格,列出了互相排斥以互相包含的狀態配對。當互相包含的狀態中的前者被設定時,後者也會跟著被設定。當互斥的配對中前者被設定時,後者將會被清除。這些規則的應用就像利用.madState script設定狀態一樣:他們不會呼叫lua函式,因此不會觸發動畫。

聲明
本文件主要是翻譯自Relic Developers Network所釋出的「HW2_MadState.pdf」。
翻譯者為西加拉宇宙載具改裝中心的CQD。原始文件版權為Relic所有。