| 執筆バージョン: Unreal Engine 5.5 | 
 
こんにちは!
今回はUMGでアニメーションを再生するための関数についてまとめていきます、良ければ確認用にお使いください!
 
UE4時代から実装されている再生停止関数
表題の通り、UE4時代から標準機能として用意されている関数まとめです。
基本的にUE4 → UE5 にかけてパラメータに変更は入っていません(一部挙動が変わっている関数は別途関数紹介内で追記します)
再生関数
 ○ PlayAnimation
 ○ PlayAnimationTimeRange
 ○ PlayAnimationForward
 ○ PlayAnimationReverse
 ○ PlayAnimationWithFinishedEvent
 ○ PlayAnimationTimeRangeWithFinishedEvent
停止関数
 ○ StopAnimation
 ○ StopAllAnimation
 ○ (一時停止)PauseAnimation
 
以下、詳細な解説となります。
再生関数
PlayAnimation

基本的なアニメーション再生関数です。
 ○ InAnimation:
  再生対象のアニメーション。
 ○ StartAtTime:
  アニメーションの開始秒数。ループ再生なら1回目だけこの設定が適用されます。
 ○ NumLoopToPlay:
  アニメーションの再生回数。0だとループ再生になります。
 ○ PlayMode:
  アニメーションの再生方法。Forwardなら通常再生、Reverseなら逆再生、
  PingPongなら通常再生、逆再生の順で順番に再生されます。
 ○ PlaybackSpeed:
  アニメーションの再生速度。
 ○ RestoreState:
  アニメーション再生終了時にWidgetを再生前の状態に戻すかどうか。
 ○ ReturnValue:
  再生されているアニメーションのUMGSequencePlayerが返却されます。
  ですが、Blueprintからアクセスできる関数は非常に限られているため、
  「アニメーションが再生中かを調べたい!」「アニメーションを止めたい!」ときは
  UUserWidgetクラスで定義されているIsAnimationPlayingやStopAnimationを使用します。
 
PlayAnimationTimeRange

アニメーションの開始秒数や終了秒数を指定できる関数です。
パラメータはPlayAnimationとほぼ同じですが、
アニメーションの終了秒数を設定できるEndAtTimeが追加されています(ループ再生の場合は最後の再生でのみ適用されます)
 
PlayAnimationForward

InAnimationに渡したアニメーションの再生状態によって実行時の挙動が変わります。
 ○ アニメーションが再生されていない(一時停止状態も含む)場合:
  通常再生でアニメーションの頭(0.0s)から再生され始めます(UE4ではアニメーションは再生されないままでした)
 ○ アニメーションが通常再生で既に再生中の場合:
  特に何も起きません。アニメーションが再生し直しになることもありません。
 ○ アニメーションが逆再生で既に再生中の場合:
  内部でReverse関数が実行され、逆再生の逆、つまり通常再生で再生途中から再生され始めます。
すぐ下で紹介しているPlayAnimationReverseと併用することが多いイメージです。
 
PlayAnimationReverse

PlayAnimationForwardとは反対の挙動をとります。
 ○ アニメーションが再生されていない(一時停止状態も含む)場合:
  逆再生でアニメーションの頭(0.0s)から再生され始めます(UE4ではアニメーションは再生されないままでした)
 ○ アニメーションが通常再生で既に再生中の場合:
  内部でReverse関数が実行され、通常再生の逆、つまり逆再生で再生途中から再生され始めます。
 ○ アニメーションが逆再生で既に再生中の場合:
  特に何も起きません。アニメーションが再生し直しになることもありません。
 
文字だけだと分かりにくいため動画を用意しました。
まずはこちら、用意したアニメーションとなります。
ヒストリア猫の簡易的なスライドイン/スライドアウトアニメーションです。
 
 
このアニメーションをPlayAnimationReverse説明内で記述した通りの3パターンに分けて処理してみます。
 
 
それぞれ最後にPlayAnimationReverseが実行されることは変わらないものの、挙動がはっきり異なる結果となりましたね。
 
PlayAnimationWithFinishedEvent

基本的な挙動はPlayAnimationと変わりませんが、いくつか異なる点があります。
 ○ パラメータはPlayAnimationと変わりませんが、Finishedという出力ピンが追加されており、
  アニメーション終了時にこちらのピンに処理が通ります。
  ※(この”アニメーション終了時”はアニメーションが正常に終了したときだけではなく、
    StopAnimationでアニメーションの再生を中断したときにも適用され、処理が通ってしまうため注意が必要です)
 ○ LatentNode化されているため関数内では使用できず、イベントもしくはマクロで呼び出さなくてはなりません。
 
PlayAnimationTimeRangeWithFinishedEvent

基本的な挙動はPlayAnimationWithFinishedEventと変わりませんが、
PlayAnimationTimeRange同様、アニメーションの終了秒数を指定できるEndAtTimeが追加されています。
 
停止関数
StopAnimation

InAnimationに渡したアニメーションの再生を中断します。
 
StopAllAnimation

呼び出したWidget内で再生中のアニメーションを全て中断します。
 
(一時停止)PauseAnimation

InAnimationに渡したアニメーションの再生を停止させます。
中断ではないためReturnValueで現在の再生秒数が返却されます。
この値を保持しておき、PlayAnimationのStartAtTimeに入れて実行すると停止した箇所から再度再生することができます。
 
UE5.4から実装された再生停止関数
上記で記述した関数に加え、UE5.4からは以下の再生関数、停止関数が追加されました。
再生関数
 ○ QueuePlayAnimation
 ○ QueuePlayAnimationTimeRange
 ○ QueuePlayAnimationForward
 ○ QueuePlayAnimationReverse
停止関数
 ○ QueueStopAnimation
 ○ QueueStopAllAnimation
 ○ (一時停止)QueuePauseAnimation
パラメータはQueueがついていない状態の関数のものと何も変わらず、
ただReturnValueで返却されていたUMGSequencePlayerが無くなっています。

基本的な特徴や使い分け方に関しては特に上記で説明したものと変わらないため、
こちらに関しては、全体を通してQueueの有る無しで変化するところをまとめます。
 
 
UE5.4リリースノートには以下の様に記載されています。
> 1 つのフレームで複数のアニメーション トランジションが発生する場合にパフォーマンスを向上させる、QueueAnimation メソッドが追加されました。
アニメーションを単体で再生する際に使用する、というよりは、
短い間に複数回アニメーションの再生関数が呼ばれるような状況で使用する、最適化用の関数のようですね。
 
実際にコードを見ながら処理を追うと、
 ① QueuePlayAnimation(Unreal Engine C++ API Referenceページ)が呼び出される。
 ② UUserWidgetクラスのメンバ変数であるQueuedWidgetAnimationTransitionsに情報が格納される。
 ③ NextTickでExecuteQueuedAnimationTransitions(Unreal Engine C++ API Referenceページ)が呼び出され、
  関数内でQueuedWidgetAnimationTransitionsに格納されたアニメーション情報を元に、
  PlayAnimationやStopAnimationが呼び出される。
といったフローを通っているようです。
BlueprintからPlayAnimationを呼び出すのではなくC++から呼び出すことで、
その分オーバーヘッドが削減される、というような意図であると見受けられます。
 
……と言われても、リリースノートの”パフォーマンス向上”はやっぱり見えづらいですね。
そこで検証のため、以下のような簡易的処理を組みました。
 
Desiners画面
UE標準で用意されている AICON-Green / AICON-Red / android_Icon を使用して、
簡易的なフェードアニメーションを用意しました。

Graph画面
用意したアニメーションを PlayAnimation(上) / QueuePlayAnimation(下) を使用してそれぞれ再生します。

実行
実行するとこんな感じです。
計測のためにそれぞれ3回ほどガチャガチャと再生してみていますが、見た感じだと特に挙動に違いは見受けられませんね。
 
それではUnrealInsightsを使用して処理がどのように進んでいるのか、パフォーマンスにどれだけの差があるかを確認してみましょう。
 
まずは通常のPlayAnimationからです。
赤く囲った上の部分がPlayAnimation(アイコン3つ分)を実行した際にかかった秒数となります。
202.9μsで処理が完了しているようですね。

そしてQueuePlayAnimationです。
前述した通り、QueuePlayAnimation実行時はQueuedWidgetAnimationTransitionsへの格納処理のみが行われているため、
7.5μsと短い時間で処理が完了しています。

その後、Tick内でExecuteQueuedAnimationTransitions関数の実行が行われ、PlayAnimationが実行されます。
かかった処理時間は136.6μs。確かに通常のPlayAnimationよりも70μsほど処理時間が短縮されています。

(拡縮してみると処理同士の距離感はこんな感じで、QueuePlayAnimationを実行してから4msほど経過して実行されています)

実行動画ではそれぞれ3回アニメーションを再生しました。それらの合計秒数は以下の表のとおりです。
| 1回目 | 202.9μs | 7.5μs + 136.6μs | 
| 2回目 | 84.9μs | 6.6μs + 118.2μs | 
| 3回目 | 139.9μs | 7.7μs + 14.9μs | 
| 合計 | 427.7μs | 291.5μs | 
 
 
 
 
 
 
実行環境、実行タイミングの影響はもちろんあると思いますが、
自環境ではQueuePlayAnimationの方が、136.2μsほど実行時間が短縮される結果となりました。
 
まとめ
通常のアニメーション再生時にはPlayAnimation~を使用し、
その頻度が高まったり最適化の面で処理時間等が気になる場合はQueuePlayAnimation~を検討する、といった使い分け方となります。
こちらの記事がどなたかの助けになれば嬉しい限りです。
それでは、良きUMGライフを!