2012年5月7日 星期一

自訂Kismet事件

Kismet可以讓開發者透過圖形界面編排遊戲腳本,例如當玩家碰觸開關時把門打開,或是進入門口時播放過場動畫。Kismet的基本結構是以各種不同功能的節點連接構成,節點可分為事件、行動、條件、變數。除了UE內建的功能外,開發者也可自行擴充需要的節點。在此篇簡單說明一下如何自訂事件節點。

事件節點的基礎類別是SequenceEvent,重要的屬性有:
  • ObjName [string]:編輯器顯示的名稱。
  • ObjCategory [string]:編輯器選單的分類。在右鍵選單的New Event的子選單裡會看到同名的分類選單。指定新的分類名稱會產生新的分類選單。
  • bAutoActivateOutputLinks [bool]:當事件發生時,是否自動啓動輸出連結。
  • bPlayerOnly [bool]:是否限定玩家才能啟動這個事件。

要通知Kismet某事件發生,有兩種方式。一種是呼叫Actor::TriggerEventClass()函式,另一種是呼叫Actor::TriggerGlobalEventClass()。一個事件發生會有兩個相關的Actor:
  • 一個是Originator,發起事件的Actor,即為呼叫觸發函式的Actor物件。
  • 另一個是Instigator,挑起事件的Actor,為呼叫觸發函式時傳入的Actor物件。 
 這兩種觸發方式的差別在於:
  •  TriggerEventClass():這種方式是觸發註冊在Originator身上的事件,需要在Kismet編輯器裡指定好Originator。使用者可以在建立事件前先選取場景中的物件,即可指定它為Originator。若是在Kismet裡動態產生的物件,可以透過AttachToEvent動作節點來指定Originator。
  •  TriggerGlobalEventClass():這種方式是去搜尋所有節點,觸發符合指定類別的節點。雖然不像TriggerEventClass()需要指定Originator,但這個方法比較暴力,效能較差。若事件有明確的Originator,還是使用TriggerEventClass()比較符合原本的設計。

範例


以下程式碼示範如何自訂一個著地事件節點:
class MySeqEvent_Landed extends SequenceEvent;

defaultproperties
{
    ObjName="Landed"
    ObjCategory="Physics"
    bAutoActivateOutputLinks=true
    bPlayerOnly=false
}
然後在專案自訂的PlayerController上覆寫NotifyLanded事件啓動MySeqEvent_Landed:
event bool NotifyLanded(Vector HitNormal, Actor FloorActor)
{
    TriggerEventClass(class'MySeqEvent_Landed', FloorActor);
    return super.NotifyLanded(HitNormal, FloorActor);
}
測試用的Kismet

沒有留言:

張貼留言