範例
以下程式碼示範如何自訂一個可以取得按住時間的按鍵綁定格式:
class MyPlayerInput extends PlayerInput within MyPlayerController native; var input float fPressingTime; var native const Map{FName,FLOAT} NameToPressedTime; cpptext { // UInput interface. virtual UBOOL Exec(const TCHAR* Cmd, FOutputDevice& Ar); }由於玩家可能會同時按住多個按鍵,所以在此使用一個map記錄不同按鍵的按下時間。按住時每個frame都會接到IE_Repeat事件,更新到指定的欄位即可:
UBOOL UMyPlayerInput::Exec(const TCHAR* Cmd, FOutputDevice& Ar) { TCHAR Temp[256]; if( ParseCommand( &Cmd, TEXT("PRESSINGTIME") ) ) { FLOAT* Button; if( ParseToken( Cmd, Temp, ARRAY_COUNT(Temp), 0 ) ) { if( (Button = FindAxisName(Temp)) != NULL ) { switch( CurrentEvent ) { case IE_Pressed: NameToPressedTime.Set(Temp, GWorld->GetWorldInfo()->RealTimeSeconds); break; case IE_Released: NameToPressedTime.Set(Temp, 0.f); break; case IE_Repeat: FLOAT* PressedTime = NameToPressedTime.Find(Temp); if( PressedTime && *PressedTime > 0.f) *Button = GWorld->GetWorldInfo()->RealTimeSeconds - *PressedTime; break; } } else Ar.Log( TEXT("Bad Button command") ); } else Ar.Log( TEXT("Bad Button command") ); return TRUE; } return Super::Exec( Cmd, Ar ); }FindAxisName()實際上並不會區分按鈕或類比軸,而是只找浮點數欄位,所以在此是用FindAxisName()而不是FindButtonName()。在Exec()中是取得不到原來觸發命令的綁定按鍵,所以退而求其次,map的鍵值是採用指定的欄位名稱。
要使用時,記得要在DefaultInput.ini裡設定,例如:
.Bindings=(Name="SpaceBar",Command="PressingTime fPressingTime")
沒有留言:
張貼留言