UE5 実践的で汎用的なアニメーションシステム設計について
この記事はUnreal Engine (UE) Advent Calendar 2023の25日目の記事です。
Advent Calendar最終日となる本日は2023年におけるUE5の時代でも使える実践的かつ汎用的なアニメーションシステムの設計についての話をします。UEにおけるアニメーションと言えば、Animation Blueprint(以下ABP)を使ってステートマシンでAnimation Sequence(以下AS)を再生するわけですが、当然ながら大きくなりすぎるとキャラクター数が増えれば増えるとほど破綻していってしまいます。
大規模なプロジェクトではキャラクターが増えてもある程度汎用的に運用できるような設計を求められるわけですが、実際のところどのように作っているかはわかりにくいので、なるべく具体例に沿って解説していきたいと思います。
前提条件
まずは前提条件を定義しましょう。
まずキャラクタースケルトンは全て共通ということについてですが、UEでは共通のアニメーションを再生したり、共通のABPを利用するためにはスケルトン(ボーン構成)が必要になってきます。これについては以下の記事でわかりやすく解説されています。
次にABP内で再生するアニメーションを決めるステートマシンですが、これは複数のキャラクターで共通のものを使いたいというニーズが間違いなくあります。この場合はスケルトンさえ共通のものがあれば同じステートマシンを共有可能です。
再生されるアニメーションはキャラクターごとに当然別のものを再生するはずです。キャラクターが違えば使用するステートマシンは同じでも違うASを再生するようにします。
キャラクターが物理などで専用のセカンダリーアニメーションが存在する場合、固有の処理として再生させる必要があります。これは共通処理とは別のものを用意する必要があるでしょう。
これら前提条件を全て満たしたアニメーションシステムをどのように設計すればよいのか見ていきましょう。
スケルトンの共通化
何はともあれ汎用的なシステムを作るためにはキャラクターのスケルトンを共通化することは必須です。UE5であれば、SK_Mannequinというスケルトンがテンプレートに最初から入っていますが、これを基本とされており、マケプレアセットを使ったりする場合であればこちらに合わせるのが無難です。UE4からの時代のものであれば、Mannequin_UE4というフォルダーに過去のスケルトンも入っていますので、こちらでなければマズい場合はこちらに合わせておきます。
アニメーションレイヤーで共有
ステートマシンを共有する前にここではアニメーションレイヤーについての紹介をしておきます。アニメーションレイヤーとは既存のABP内で別のABPの処理を実行し、同時に処理することができる仕組みです。そのためにはアニメーションレイヤーインターフェースが必要になります。それらをリンクさせることをAnimation Blueprint Linkingと呼ぶそうです。
アニメーションレイヤーインターフェースはBPのインターフェースと同様に継承関係などを持たないABP同士でも呼び出しが可能となるため、肥大化していくABPを依存関係をもたないままで拡張していくことが可能となります。詳しい使い方は公式ドキュメントにありますので、参考にしましょう。※ドキュメントはUE4の解説となっていますが、基本はUE5でも同様
アニメーションレイヤーで共有させるためには少し複雑なABP構造が必要になってきます。以下の画像を元に個別に説明します。
- BP_Character → キャラクターを動かすためのBP。ABP_AnimCommonをMeshに設定し、ABP_Characterをリンクする
- ABP_AnimCommon → BPから直接設定される共通ABP。インターフェースからABP_AnimLayerの処理を呼び出す
- ALI_AnimInterface → ABP_AnimCommonとABP_AnimLayerが持つインターフェース。実装は存在しない
- ABP_AnimLayer → ABP_AnimCommonから呼び出されるABP。メインのアニメーション共通実装を持たせる
- ABP_Character → ABP_AnimLayerから継承するABP。共通処理を持ち、BP_CharacterがリンクするABP
BP_Characterを起点に、ABP_AnimCommonがベースのアニメーション処理を呼び出します。この中の実装はALI_AnimInterfaceで共通インターフェースを経由し、その中でABP_AnimLayerの処理が呼び出されることになります。ABP_CharacterはABP_AnimLayerを継承しています。ABP_AnimLayerにはアニメーションの共通実装を持たせ、ステートマシンを共有させることになります。更にBP_CharacterはABP_Characterとリンクを行います。BP_CharacterとABP_Characterはキャラクターの数ごとに存在し、最終的にキャラクターごとに違うABPが呼び出されることになります。
これでABP_AnimLayaerでステートマシンを共有することが出来るようになりました。もちろんABP_AnimCommonとABP_AnimLayerは依存関係を持たないので、全く違うABPをレイヤーとして持たせることで、そのキャラクターに特化したABPを持たせることも可能となります。これにより汎用性と専門性を両立するようなABP構造を持たせることができました。
再生するアニメーションを選ぶ
次はキャラクターごとに再生するアニメーションを変更させるようにしてみましょう。これは通常のステートマシン内でアニメーションを選択する際に少し手間をかけます。ABP_Layer内で以下のような処理を作ったとしましょう。
通常のSeqence Playerにピンを公開した状態でAnim Sequence Baseのリファレンス変数を持たせます。この変数には特に何も設定してもいいですし、設定しなくてもいいです。依存関係を持たせないのであれば極力設定しない方がよいでしょう。
次にABP_AnimLayerを継承したABP_Characterの方を開きます。右上の詳細に注目してみましょう。
変数にASが設定できるようになっています。これで個別のアニメーションをキャラクターごとにオーバーライドすることが可能です。アニメーションを設定しないことも選択できますが、汎用的なアニメーションであれば全て設定しておきましょう。これでどのようなキャラクターであっても共通処理で個別のアニメーションを選択することができるようになりました。
物理などの専用アニメーション
物理処理(例えばキャラクターの髪やスカートなど)はほとんどの場合キャラクターごとに違う処理になることがほとんどです。この場合、既存のアニメーション処理とは独立してアニメーションを設定可能です。UE5ではそのような処理をPost Process Animation Blueprintで作成しましょう。あまり情報はないのですが設定方法自体は簡単です。
スケルタルメッシュエディター(ペルソナエディター)を開いて、詳細の中にPost Process Anim Blueprintを設定するだけです。
設定を行うとアニメーションをエディター上で開くだけで自動的に物理などの専用処理が動作しています。このABPを無効にしたい場合はワンボタンで無効化することも可能です。
ちなみにこのABPそのものは名前の通り既存のABPの後から実行されることになっています。そのため、位置に依存するような処理を含めることは厳しいので、基本的には物理などのセカンダリーアニメーションのみを含んでおくことを推奨します。もし他に専用処理が必要な場合は、ABP_AnimLayerとは別のレイヤーで処理させるかなどの対応が必要です。
参考
UE5 Chaos RBAN(Rigid Body Animation Node)でキャラクター物理を制御しよう - Let's Enjoy Unreal Engine
まとめ
いかがでしたでしょうか。このような汎用処理を作るメリットは実際に一定以上の規模のプロジェクトでないと感じにくいかもしれませんが、確実に開発効率に効いてくるものです。UE5では他にもGameplay Ability System(GAS)を使ってステートマシン以外の部分もアニメーションも汎用化させることが可能です。GASは使いこなすと便利ですが、とても複雑なものなのでここでは取り上げません。
興味がある人はアニメーションモンタージュとルートモーションについて深く調べてみることをお勧めします。UE5にはまだまだ多くのアニメーションシステムが存在しますので、ぜひ使いこなしてみてください。最後にお勧めの参考資料を紹介しておきます。
猫でも分かる UE5.0, 5.1 におけるアニメーションの新機能について【CEDEC+KYUSHU 2022】 | ドクセル
猫でも分かる UE4のAnimation Blueprintの運用について【Unreal Engine Meetup Nagoya #6 in 名古屋城】 | ドクセル
Unreal Engine の開発が楽になる便利機能を紹介 DataAsset, Subsystem, GameplayAbility編 | ドクセル