Let's Enjoy Unreal Engine

Unreal Engineを使って遊んでみましょう

UE5 Property Accessを使ってAnimBPをマルチスレッドに更新しよう

UE4では元々アニメーションブループリント内のAnim Graph内であれば条件付ですが、Game Thread以外で更新が可能でした。そしてUE5となり、Event Graph上でもなんとGame Thread以外での更新が可能となりました。

しかし、マルチスレッドに実行するということは変数やオブジェクトのアクセスはスレッドセーフ(スレッド上に安全に更新が可能なこと)であることを保証する必要があります。そのために用意されたのが"Property Access"と呼ばれる新機能です。名前だけをみるとプロパティ(なんらかの入れ物)にアクセスするゲッター、セッターの機能かな?と勘違いをしますが、このProperty Accessはもっと高度な機能です。

では例と一緒にProperty Accessとマルチスレッドでの更新についてを解説していきましょう。

Property Accessについて

Property Accessプラグインとして提供されていますが、UE5では標準でオンとなっているプラグインですので、特に何かをしなくても標準で利用することが出来ます。プラグインを検索すると、"Property Access Node"というプラグインがあることがわかります。"Property Access Editor"というプラグインもありますが、こちらは直接関係するプラグインではありませんので、特に気にしなくてもよさそうです。

あとはアニメーションブループリントのEvent Graph上で"Property Access"と検索するとノード一覧に表示されます。日本語ではカタカナとなっていますが、英語で検索してから選んでもらえば問題ありません。これでProperty Access自体を扱うことができるようになります。

ノードから"バインド"の文字をクリックすることで、そのアニメーションブループリントが持つアクセス可能なプロパティ一覧が表示されますので、アクセスが必要なプロパティを選択することでバインドされます。必要となるプロパティを一覧から選択してください。


BlueprintThreadSafeUpdateAnimationを利用

アニメーションブループリントを作成し、関数のオーバーライドから"BlueprintThreadSafeUpdateAnimation"を選択します。

この関数はブループリントでありながら自動的にワーカースレッド上で実行されるようになっており、通常のEvent Graphとは違ってローカルなプロパティ以外にアクセスするとエラーがでるようになっています。以下のような場合はローカルなプロパティでGround Speedが存在するため常にスレッドセーフとなり問題はありません。

次の例は外部オブジェクト参照へアクセスしているため、スレッドセーフではないためにエラーとなってしまいます。

これをスレッドセーフ、もしくはアクセス可能な状態へと修正するのがProperty Accessです。エラーとなった例を修正する場合は以下のようになります。

エラーがなくなりました。ただしこれはスレッドセーフではありません。Propery Accessは自動的に外部オブジェクトなどがアクセス可能なタイミングを判断し、プロパティがキャッシュをとって同期するタイミングを設定してくれるようになっています。今回はEvent Graphの更新が入る前のGame Thread上で同期が行われるようになっています。外部オブジェクトは参照をもっていますが、直接コピーすることができないのでGame Thread上での更新となってしまう制限が存在しています。これは仕方ないですがBlueprintThreadSafeUpdateAnimationはワーカースレッド内で実行され、マルチスレッドに更新されているのでGame Threadへの負荷はほとんどありません。

更新タイミングを指定する

Property Accessは同期を行う更新タイミングをある程度指定することができます。Property Accessの呼び出しサイト(Call Site)から6つの更新タイミングから選ぶことが可能です。


  • 自動 → デフォルト。自動的に同期可能なタイミングを選んでくれます。
  • スレッドセーフ → Anim Graphもしくはワーカースレッド上で同期を行います。
  • ゲームスレッド(プリイベントグラフ)→ Event Graphが実行される前にGame Threadで同期を行います。
  • ゲームスレッド(ポストイベントグラフ)→ Event Graphが実行された後にGame Threadで同期を行います。
  • ワーカースレッド(プリイベントグラフ)→ BlueprintThreadSafeUpdateAnimationが実行される前にWorker Threadで同期を行います。
  • ワーカースレッド(ポストイベントグラフ)→ BlueprintThreadSafeUpdateAnimationが実行された後にWorker Threadで同期を行います。

基本的には自動で問題ありません。また外部オブジェクト参照を持つプロパティの場合はGame Thread上で同期する以外の選択肢はありません。とは言え、BlueprintThreadSafeUpdateAnimation自体はワーカースレッド上で更新されるので、十分効果はあるはずです。

アニメーションブループリントのみで、C++に頼らなくともマルチスレッドにEvent Graphの情報を更新できるのは大きい負荷軽減が可能となります。ぜひアニメーションロジックを作り込みたい人は活用してみてください!