ALSの仕組みで上半身だけにリロードなどの特別な動作のアニメーションモンタージュ再生をしたいが、なぜかできない問題を修正しました。
yossi40-100/GASP-ALS: Game Animation Sample with ALS Layering
原因
GASP-ALSが採用しているLinked Anim Graphでは別の子ABP内でSlot再生をしようとしていて、これはおそらく仕様上できないことをやろうとしています。多分その部分全くテストされていません。

↓その中身で、誰もが一度は見てそっと閉じるALSのコア部分


同じことの繰り返しなので、実はそれほど難しくなかったです。最後の部分のカーブスロットの扱いだけまだ理解してないけど、そこが重要そうなコメントが書いてあるので悩ましい。
上述のような構成にした理由はGASPの進化時にALSの仕組みを再反映させる手間の削減とのこと。
一方、本家Advanced Locomotion Systemでは、親のABP上にコア部分が実装されているので、問題なくモンタージュ再生できていました。
なので、GASP進化時の移植性をあきらめて、ABP_SandboxCharacter自体に実装すれば解決できます。

ChatGPTに相談したらLinkedAnimLayerならできるよっていうから、試しにAnim Layer Interface作って親子ともにそれを実装して、ってやってみたが、、、結局できないじゃん!
って問い詰めたらできませんと意見を変えてくる。。。
修正
ということでお引越し大作戦。
コア部分
ABP_SandboxCharacterに新規アニメーションレイヤー「LayerBlending」を追加し、ABP_LayerBlendingのAnimグラフをコピペします。

すると入出力はコピペできないので上図赤枠のところを接続します。
入力は「マイブループリント」タブでLayerBlendingレイヤーを選択した状態で詳細欄から追加すると左端のほうにできるのを持ってきて、コピー元と同じようにつなぎます。


これで完成なら、めでたしめでたしといったところですが、
コンパイルエラーになるのでいろいろメンテが必要です。
まずエラーになっているこのプロパティアクセスノードは、
すでにイベントグラフ上の処理でスタンス変数に取得されているので置き換えるだけでOKです


次にこの空間ごとの計算用のベースポーズは変数にバインドされていますが、
そう変えるものじゃないので、単純なピンにして設定してしまえばいいかなと思います


変数未定義警告はすべて作成しましょう。コンパイル後に警告が消えます。


これで完成、ではありません。
前処理部分
今作った変数たちはオーバーレイポーズのアニメーションシーケンスでどのように加算するかを定義するカーブ情報です。勝手に入力はされないので、自分で更新してあげる必要があります。

マクロがコピペできないようで、実はこっちの移植がかなり面倒でした。

ちまちま手作業しましたが、皆さんは、私の公開リポジトリ上のABP_SandboxCharacterから簡単にコピペできるように、マクロなし版にしておきました。
新規関数「UpdateLayerValue」を作成し、コピペします。自力でやる方はマクロを先にコピーして、マクロにカーブ名を入力していく感じですね。

Hand-IK制御
上の図で、既に入れていますが、追加でハンドIKを無効にするための仕組みを導入しています
Ignore_HandIK というカーブ名で、その値をもとのEnable_HandIK_Lなどから決まるIK補正の強さから減算する仕様としました。


ちなみに、Layering_Arm_LがEnable_HandIK_Lを弱めるって関係性になっているということもここでわかりますね。
逆にその関係性が邪魔な場合(通常は弱めに加算するポーズだけど、モンタージュではIKをがっちり100%利かせたいなど)は、このあたりの計算を工夫してください。
使い方
オーバーレイ中に再生したいモーションをアニメーションモンタージュ化し、下図のようにスロットをDefaultGroup.Arm_R など部位を選び必要なだけ複製します。

あとは、CBPなどからPlayMontageノードなどで、再生してあげるだけです。


キー入力で動かす具体例は動画で。また動画でも割愛していますが、発射のアニメーションは開始時のフレームからの差分だけを加算しないとおかしな動きになります。
リロードのアニメーションはIgnore_HandIKカーブを使ってエイム中などのハンドIKを途中まで無効化して、最後銃を握るところだけ有効に戻しています。


動画ではUpperBodyスロットを使えるようにする話もしていますが、ここでは割愛します。
おまけ(所感やTODOなど
やってみた結果、カーブの値をモンタージュで上書きするのが難しいようで、オーバーレイのポーズと違う設定にしたい場合は、この仕組みを使って再生するのは向いてなさそう。
(Idle状態ではそれっぽいが、走りながらリロードをArm_Lスロットに流すと、左手がくちゃくちゃになる(加算の設定の違い))
この仕組みを使うべきなのは、エイム状態からの発砲など加算のアニメーションと思われる。 リロードは加算って感じじゃないので別途上半身強制上書きで再生するUpperBody Slotを用意したほうがよさげ。AnimGraphでDefault Slotの手前にLayered Blend Per Boneで追加(動画ではそこも解説)。
Layered Blend Per BoneにSpine_02でMesh空間で回転にチェック。
走っていてもリロードっぽい動作にできた。
が、カバー時(キャラの向きに対してメッシュが180度回転)に上半身だけ前向くねじれが。 → Mesh空間で回転のチェックを外したら自然になったのでこっちのほうがよいか。(カバーの解説がまだなので、それもやらなきゃ)
TODO: トラバーサル中もリロードできちゃったり、リロード中にも弾撃てちゃうのはDoingTraversalActionフラグとかでキャンセルできるはず。
TODO: スローで見ると新しいマガジンと左手がずれまくっている
HideBoneでマガジンをスケルタルメッシュから消して、別途物理シミュレーションのスタティックメッシュをスポーンさせて落下させ、腰に手を当てたタイミングで新しいマガジンをスポーン ってのを通知使ってやるのが比較的シンプルでリアルかな。
別案は、Lyraのpistol側のリロードのマガジンの動きにHand-IKの目標を動かし補正。
コメント