在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 );
}
}
}
沒有留言:
張貼留言