UObject の任意関数の検索と実行

UE4 はリフレクションのおかげで、UObject の任意関数の検索、実行が簡単にできる。
LevelScriptActor の RemoteEvent なんかはこれを使っている。

関数検索

// FName で登録されている関数を検索する
UFunction* UObject::FindFunction( FName InName ) const;
 
// FName で登録されている関数を検索する(見つからなかったらFatalログ出力)
UFunction* UObject::FindFunctionChecked( FName InName ) const;

関数実行

UObject::ProcessEvent( UFunction* Function, void* Parms );

例えば、引数なしでコールするだけなら以下のように実装すればすぐに使用できる。

// AMyActor は AActor 継承
 
bool AMyActor::CallFuncByName(const FName& FuncName)
{
    auto* Func = FindFunction(FuncName);
    if (Func && Func->NumParms == 0) {
        ProcessEvent(Func, nullptr);
        return true;
    }
    return false;
}

Parms 自分でメモリ確保してポインタで渡す必要があるっぽいのでちょいと面倒。

コマンド形式での実行

コマンド形式で呼び出すなら UObject::CallFunctionByNameWithArguments を使用する手もある。
引数付きでコールしたい場合はこっちのほうがいいかも。

Just a moment...

余談:Sequencer – Event Track

Sequencer の Event Track では、最近のバージョンでは引数渡しでイベント実行ができる。
MovieSceneEventTemplate の実装を見る限り、以下のような仕様になっている。

  • FEventPayload でイベント名(FName)ごとに引数を UStruct で引数を管理する
  • 実行すべきタイミングで、そのイベントを保持しているオブジェクト(複数可)を取得
    • ObjectBinding されていない場合、IMovieScenePlayer::GetEventContexts() から取得
    • (LevelSequencePlayer の場合は UWorld が渡される)
  • 取得したオブジェクトごとに 1 つずつ ProcessEvent で実行する

コメント