目次
はじめに
今回は大幅にアップデートされたアニメーション機能において、次の内容を参考に現時点で考えるメンテナンス性や拡張性を考慮したアニメーション設計についてまとめています。
設計において、人それぞれの思想があるのはもちろんのこと、今後のエンジンのアップデートでより良い手法が出てくる可能性があります。
そのため、投稿者個人が時点での最新の環境のUE5.1.1を使用した設計ですので参考程度に見ていただければいいと思います。とは言えUE4から大幅に進化したABPは手を動かす価値が十分にあるので挑戦していただければ嬉しいです。
前提として、UE4のサードパーソンテンプレートなど基本的なアニメーションブループリントの使い方を知っている方をターゲットにして書いています。
事前に公式のドキュメントを見ていただくとより理解しやすいかと思います。
またアニメーションブループリントは以降ABPと省略して呼称いたします。
目指すべき”いい設計”ってどんなの?
今回、考えるアニメーションのいい設計は再利用性と拡張性です。
逆に悪い設計のABPを参考にいくつか挙げると以下の実装です。
➀ 特定キャラだけ持っている変数をABPが参照(Cast)している。
② 同じようなステートマシンがさまざまなABPで書かれている。
③ 新しいキャラクターやアクションを追加しようとするとABPの大改造が必要になる。
では一体これらを回避するにはどうすればよいでしょうか?
そもそもUE4でのアニメーションは(プラグインを有効にしない限り)スケルトンアセットとアニメーションアセット(アニメーションシーケンサー,ABP,BlendSpace,Montage,etc.....)が常に紐づいていました。
こうなってしまうと骨格の異なるキャラクター同士でのロジックの共有が非常に困難となります。
一度作ったプレイヤーABPのステートをモンスターABPにコピぺしたりといったことをしたことがある方は多いのではないでしょうか。
まずは、どんなスケルトンアセットが来てもロジックを使いまわせるような”再利用性”に焦点を当てていきます。
ロジックを再利用する
UE5からはプラグインを有効にせずともアニメーションテンプレートが作成できるようになりました。
アニメーションテンプレートは特定のスケルトンに依存しない抽象化されたABPです。
そのためテンプレートにロジックをすべて書き、継承先でスケルトンとアニメーションを設定することができる最高なシステムです。
作り方は簡単でABP作成画面でテンプレートを選ぶだけです。
このABPでは特定のスケルトンとの依存が発生しないので、強い依存関係のあるアセットをここに配置することはできません。
例えば、アニメーションシーケンスやブレンドスペースが該当します。
肝心のアニメーションが配置できないとステートマシンすら作れないじゃん!!となってしまうのでアニメーションテンプレートにはPlayerが存在します。
プレイヤーは種類ごとに存在し、特定の種類のアニメーションを受け付ける窓口となります。
特によく使うSequencePlayerを例にして説明するとAnimSequenceBase型の変数をここにバインドすることができます。
※ブレンドスペースもノードとして置けるようになりましたが、継承後に独立したアセットとして差し替えたいのでPlayerノードで変数化したものを適応することをお勧めします。
これを使用することで移動、ジャンプ、などキャラクターが共通して持つロジックを作ることができます。
通常のABP同様に移動速度やジャンプしているかなども設定できます。
(以下はスレッドセーフを使用した高パフォーマンスな手法)
ただ気を付けてほしいのはここでは抽象化されたABPなので特定のキャラクターへのCastを行うのは思想と反しますのでしないでください。
インターフェースで抽象化することを強くお勧めします。
BPのインターフェースって何ぞやという方は過去記事をお読みください。
作成したテンプレートは右クリックからスケルトンを指定して継承することで特定のスケルトンのABPとして利用することができるようになります。
継承後のABPにはアニメーショングラフが表示されない代わりに作成した変数を設定することができます。
これを利用することで異なるスケルトンでもアニメーションをポイポイ適応するだけで同じロジックを利用することができるようになりました。
しかし、残念なことにこの設計には欠陥があります。
それは、アニメーションロジックの共通化をしたこと故に、テンプレートABPのロジックがどんどん肥大化していきます。
特に攻撃パターンをステートマシンで種類別に書いた場合、そこらへんの小鳥がラスボスの攻撃パターンを持っていることになります。
これだと、パフォーマンスに影響が出るだけでなく膨大な量のいらない変数が出てくるため、セットアップも大変になります。
以上のことを踏まえて、処理を抽象化することでの”拡張性”に焦点を移していきたいと思います。
処理の抽象化をする
先ほど書いたように、テンプレート継承後のABPはアニメーショングラフは編集できないので、アニメーションレイヤーインターフェースという機能を使って、一部のAnimGraphロジックを抽象化して、外部で作成したロジックのプリセットを付け外しできる仕組みを作ります。
ここでは、通常のABPとごちゃ混ぜになってしまうのでこの付け外し用のABPをレイヤーABPと勝手に呼称します。
▼全体像 (小鳥用攻撃ABPとかがレイヤーABP)
抽象化するためのアクションを定義します。
アニメーションレイヤーインターフェースを作成します。
名前をALI_CombatLayersとしました。
Attack_StateとAdditive_Bodyを追加しました。
Additive_Bodyはポーズを入力を追加しています。(これは名前が抽象化すぎて不適切)
テンプレートアセットにアニメーションレイヤーインタフェースを実装します。
アニメーションレイヤーに追加した関数が出てくるのでAnimGraphにドラッグするとLinkedAnimLayerが出てきます。これを組み込むことで内部のステートマシンなどで抽象化された実装を定義できるようになりました。
▼ここの実装ができました。
では実際にロジック用のレイヤーABPを作成します。
このABPは”小鳥の”や”ドラゴンの”など専用のスケルトンが決まっているので通常のABPの作成時と同じようにスケルトンを選択して作成します。
このABPはテンプレートABPとは全く関係ないので注意!!
作成したら、レイヤーABPにもアニメーションレイヤーインターフェースを実装します。今回はALICombatLayers
アニメーションレイヤーに作成した関数が出てくるので上書きしたい処理を書いていきます。
例➀: インプットの引数がある場合は、骨の一部を変形させたり、LookAtやIKを適応できる。
例②: 独自のステートマシンや遷移を組み込む
※このレイヤーABPでは作成時にスケルトンを選んでいるので直接アニメーションアセットを配置することができます。
このようにテンプレートで使用しているロジックの中身を独立したABPに書くことができます。
▼これができました。
最後にどの攻撃ロジックを適応するかをキャラクターBPから選択します。
LinkAnimClassLayersからどのレイヤーABPのロジックを利用するかを選択できます。
これでテンプレートのロジック内で利用される分離した攻撃ステートを自由に上書きできるようになりました。
注意 : 1つのアニメーションレイヤーで定義した関数をそれぞれ異なるレイヤーABPを利用することはできません。セットで適応されます。
これをうまく活用すると、HPが一定以下になったとき攻撃パターンが変化する敵の実装や、装備したものによって異なるステートマシンを使う仕様をLinkAnimClassLayersのアセットを切り替えるだけで簡単に実装できます。
もし、あなたのゲームにDLCコンテンツを追加するとき、ABPのテンプレートには一切触らず済む設計も可能になります。
追加コンテンツ用のレイヤーABPに書いて、それを呼び出すだけで実現できます。
これができるのは拡張性を考慮した設計のおかげです。
またアニメーションに関わらず設計についての本はいろいろあります。
この機会に学習してみるのもいいかもしれません。
補足UE5.4.3のTPテンプレートで今回の実装を行ってみました。
アセットの構造はこんな感じ、BP_ThirdPersonCharacter以外は新規アセットです。
中身はこんな感じレイヤーインターフェースはSampleという内容で男性女性のスタイルで切り替える実装をしています。
これでABP_Template_Child_Humanを参照してますが登録するスタイルによって異なるアニメーションを行います。
最後に
今回の設計により共通したロジックを使いまわし、独自のロジックは外部から切り替えることができるようになりました。
ここで触れた内容以外にもBPとABP間の連携のために、インターフェースやGameplayTagPropertyMapやGameplayAbilityの活用などいろいろ考えることはありますが、アニメーション設計の参考になればうれしいです。
UE4やUE5向けの記事を書いています。
皆様の応援が投稿のモチベーションになりますので
コメントやTwitterのフォローなどしていただけるとありがたいです。
それではよきゲーム開発を。