在Matinee編輯器中,左邊看到軌道名稱是寫在InterpTrack類別的TrackTitle屬性,左邊的圖示則由GetTrackIcon()函式指定。而按右鍵新增軌道時顯示的名稱是寫在當地化組態檔Descriptions.int裡。所以當自訂軌道時,記得要去新增一個名稱設定。
InterpTrack可以指定另外兩個擴充類別:
- 其中一個是實例類別,用來維護執行狀態,由TrackInstClass屬性指定。
- 另外一個是輔助類別,用來擴充編輯功能,由GetEdHelperClassName()函式指定。
一般而言,自訂InterpTrack通常也需要自訂實例類別,但輔助類別就不是每個InterpTrack都需要。
InterpTrack是以keyframe的方式記錄在預定時間點的屬性值,不同型別的屬性需要不同型別的記錄資料,所以InterpTrack類別本身並不會定義記錄記錄資料,而讓子類別來決定。InterpTrack會呼叫虛擬函式來通知子類別相關的事件,例如新增、刪除keyframe。所以InterpTrack的子類別可以覆載虛擬函式來擴充功能,以下列出重要的擴充函式:
- AddKeyframe(Time, TrackInstance, InterpMode):在指定時間點新增一格keyframe。傳入的軌道實例物件型別會根據TrackInstClass屬性決定。
- RemoveKeyframe(KeyIndex):刪除指定索引的keyframe。
- UpdateKeyframe(KeyIndex, TrackInstance):更新指定索引的keyframe的值。通常作法是從傳入的軌道實例物件取得目前作用中的Actor,然後取得Actor上相關屬性目前的值,更新到指定索引的keyframe。
- UpdateTrack(NewPosition, TrackInstance, bJump):更新物件屬性值到指定的時間點。通常作法是利用keyframe記錄資料計算出指定時間的屬性值,然後更新到TrackInstance作用中的Actor身上。
範例
下列程式碼展示如何自訂一個可動態變更DrawScale屬性的軌道。其實使用InterpTrackFloatProp可以達到相同效果,不過它會呼叫Actor類別的ForcedUpdateComponents()函式來暴力更新,而我們可以此呼叫比較有效率的Actor::SetDrawScale()。為了簡化範例,在此繼承自InterpTrackFloatBase,它定義一個型別為InterpCurveFloat的屬性叫FloatTrack來存放keyframe資料。
class MyInterpTrackDrawScale extends InterpTrackFloatBase native(Interpolation); cpptext { // InterpTrack interfaces virtual INT AddKeyframe(FLOAT Time, UINterpTrackInst* TrackInst, EInterpCurveMode InitInterpMode) { INT NewKeyIndex = FloatTrack.AddPoint( Time, 0.f ); FloatTrack.Points(NewKeyIndex).InterpMode = InitInterpMode; UpdateKeyframe( NewKeyIndex, TrackInst ); FloatTrack.AutoSetTangents(CurveTension); return NewKeyIndex; } virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrackInst) { AActor* Actor = TrackInst->GetGroupActor(); if( Actor && FloatTrack.Points.IsValidIndex(KeyIndex) ) { FloatTrack.Points(KeyIndex).OutVal = Actor->DrawScale; FloatTrack.AutoSetTangents(CurveTension); } } virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrackInst) { UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrackInst) } virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrackInst, UBOOL bJump) { AActor* Actor = TrackInst->GetGroupActor(); if( Actor ) { FLOAT NewFloatValue = FloatTrack.Eval( NewPosition, Actor->DrawScale ); Actor->SetDrawScale( NewFloatValue ); } } } defaultproperites { TrackInstClass=class'MyGame.MyInterpTrackInstDrawScale' TrackTitle="Draw Scale" }我們需要自訂對應的實例類別MyInterpTrackInstDrawScale,用來在編輯器預覽時記錄和恢復DrawScale。但不需要使用輔助類別。
class MyInterpTrackInstDrawScale extends InterpTrackInst native(Interpolation); var float SavedDrawScale; cpptext { virtual void SetActorState(UInterpTrack* Track) { AActor* Actor = GetGroupActor(); if( Actor ) { SavedDrawScale = Actor->DrawScale; } } virtual void RestoreActorState(UInterpTrack* Track) { AActor* Actor = GetGroupActor(); if( Actor ) { Actor->SetDrawScale( SavedDrawScale ); } } }
沒有留言:
張貼留言