記事執筆時Unreal Engineバージョン:5.2
解決方法
アニメーションモンタージュ再生ノードのOnInterruptedピンが自身をDestroyActorするノードに繋がっている可能性があります。OnInterruptedピンを外せばエラーは解消されます。
概要
OX ENGINEER STUDIOでクライアントエンジニアをしている林です。
UnrealEngine5(以下UE5)にてアニメーションモンタージュの再生処理を実装した際に、プレビューを停止するとエラーが発生してUE5エディタが強制終了する現象に遭遇しました。
本記事では、アニメーションモンタージュの再生によって「Assertion failed: bRegistered」エラーが発生する原因と実例について記載します。
アニメーションモンタージュとは
アニメーションモンタージュは、アニメーションのブレンドやアニメーションシーケンスの編集、アニメーション通知の追加などの機能を使用してアニメーション再生のコントロールが行えるアセットです。
参考:アニメーション モンタージュ
https://docs.unrealengine.com/5.0/ja/animation-montage-in-unreal-engine/
アニメーションモンタージュを使用するケースの1つとして「処理に応じたアニメーションを再生し、アニメーションの終了後に処理を行う」ケースが考えられます。
そして、アニメーションモンタージュの終了待ちの方法として冒頭の画像のようにアニメーション終了時の実行ピンを後続のノードに繋げる方法をとることが多いです。
エラー:Assertion failed: bRegistered
殆どの場合、アニメーションモンタージュの終了待ちは上記の方法で問題ありません。
しかし、終了待ちの後に行う処理の内容によって、エラーが発生する可能性があります。
エラーの発生原因
アニメーションモンタージュ再生ノードのOnInterruptedピンが、自身のActorを破棄するDestroyActorノードに繋がっている場合、アニメーションモンタージュ再生中にプレビューを停止すると、「Assertion failed: bRegistered」エラーが発生します。
このエラーは、エラーメッセージの通りActorComponent.cppで発生します。
エラーメッセージに記載されている1042行目(行数はUE5のバージョンによって異なる)は、以下の関数「OnUnregister」です。
「Assertion failed: bRegistered」のメッセージから、最初のチェックマクロ「check(bRegistered)」のアサーションに失敗したエラーであることが分かります。
このチェックマクロは、既に破棄された、または破棄されつつあるActorを破棄しようとすると失敗します。
なぜ破棄されたActorを再度破棄するような処理になってしまうかというと、まずプレビューを停止するとワールド上のActorのEnd Playイベントが実行され、Actorが破棄されます。
そして、アニメーションモンタージュ再生ノードのOnInterruptedピンは別のモンタージュの再生によって中断された場合やアニメーションの再生に失敗した場合に実行されますが、実はアニメーションモンタージュの再生中に自身のActorが破棄された場合も実行されてしまいます。
結果、プレビューの停止とOnInterrupted後のDestroyActorで2度Actorを破棄しようとしてエラーが発生してしまいます。
エラーが発生し得る例
「アニメーションモンタージュの終了後に自身をDestroyActorする」とだけ聞くと想定されるケースが分かりにくいので、実例を考えてみます。
例えば「HPが0になると、倒れるアニメーションの終了後に消える敵キャラクター」を実装するとします。
HPが0になったら、倒れるアニメーションをアニメーションモンタージュで再生し、OnInterruptedを含む実行ピンをDestroyActorに繋げてアニメーション終了後にキャラクターを消す。
上記のように実装した場合、敵キャラクターが倒れるアニメーション再生中にプレビューを停止すると、「Assertion failed: bRegistered」エラーが発生してしまいます。
エラーを起こさないようにするためには
アニメーションモンタージュの終了後の処理で自身をDestroyActorする可能性がある場合は、OnInterruptedピンは使用しないようにしましょう。