This document is about: QUANTUM 1
SWITCH TO

Custom Animator

イントロ

Quantumの決定性アニメータはUnityのMecanim Controllerの情報をベイクすることで作用します。ステート、ステート間移行、モーションクリップなどの全ての設定をインポートします。

この機能の主なメリット は、マシン間のアニメーションを100%同期するようにコントロールできることです。ロールバックによって数フレーム前に移行が発生したことが通知されると、アニメーションが正しいステートへと切り替えます。つまり、アニメーションに基づいたかなり正確なティック が提供されます。これは全てのクライアントでシミュレーションが完全に同期されていることが求められる格闘ゲームやスポーツゲームなどで必要とされるものです。

アニメータはSDK 1.2.xバージョンには搭載されていたものでした。このアニメータツールの強化をやめたのは現在Unityのmecanim上にある依存性のためと、このドキュメントが書かれた日までに、Unityがまだ新しい安定したアニメーションツールをローンチしていなかったためです。

そのため、アニメータをquantum.stateおよびquantum.systemsプロジェクトにインポート、そしてニーズに合わせて変更、再ビルドできるオープンソースコードとして保持することとしました。

このドキュメントではカスタムアニメータのインポート方法とプロジェクト内での使用方法について説明します。Quantum 1.2.xバージョンでは、まだデフォルトのアニメータを搭載していますので、こちらは置き換えになります。

PS: このドキュメントではQuantum 1.2.xバージョンに焦点を絞った説明をしていますが、お使いのバージョンがQuantum 2.0の場合は、V2ドキュメントの同様の記事を参照してください。

カスタムアニメータパッケージをインポートする

  1. ここからカスタムアニメータをダウンロードします。;
  2. カスタムアニメータを解凍し、QuantumCustomAnimator_stateフォルダのコンテンツをquantum.stateプロジェクトに入れます。;
  3. QuantumCustomAnimator_systemsのコンテンツをquantum.systemsプロジェクトに入れます。;
    PS: 独自のカスタムアニメータコードを保持するため変更できるファイルがあります。クラスの名前はオリジナルのアニメータと同じですが、これらはすべてQuantum.Custom.Animator名前空間の配下にあり、お互いのみを参照するため旧アニメータのクラス・構造体を使用することはありません。
  4. このパッケージにはFrame.InitUserメソッドの部分実装が搭載されています。このメソッドはCustomAnimatorUpdaterの初期化を処理します。既にプロジェクトに同メソッドの部分実装がある場合はInitUser内で忘れずにInitializeAnimatorUpdaterメソッドへの呼び出しを含めるようにしてください。そして、このパッケージからFrame.User.csファイルをインポートしないでください。;
  5. 自分のソリューションに全てそろったら、quantum.systemsソリューションをビルドします。;
  6. Unityで、プロジェクトにQuantumCustomAnimator.unitypackageファイルをインポートします。;
  7. 1.2.4.2 より前のバージョンを使用されている場合は、QuantumAOT生成での修正をインポートする必要があります。codegen_unity.zipを解凍し、コンテンツを<YourProjectRoot>/tools/codegen_unityフォルダに入れます。その後、 自分のquantumソリューションを再度リビルドします

これでビルドと実行の初めのステップが完了しました。それでは、コンポーネント、アセット、ベイキングツールを実際に使用していくにあたっての説明を以下に記します。

カスタムアニメータを使用する

  • Insert the CustomAnimatorコンポーネントをエンティティに挿入します。 : use CustomAnimator;

  • Unityでは、CustomAnimatorGraphタイプのデータアセットを新しく作成します。このアセットはUnityのmecanim controllaerに関連する情報の蓄積を担います。カスタムアニメータを設定するためにはquantum側でこのアセットを見つける必要があります。 アニメータアセットを見つける方法:
    var animatorGraphAsset = DB.FindAsset<CustomAnimatorGraph>("MyAssetGUID");

  • CustomAnimatorコンポーネントを初期化する:
    CustomAnimator.SetCustomAnimatorGraph(&knight->CustomAnimator, animatorGraphAsset);

  • Unityと同様アニメータに読み取り・書き込みを行うには、GettersとSettersを使用します。

C#

// Getters
CustomAnimator.GetBoolean(&fighter->Animator, "Defending");
CustomAnimator.GetBoolean(&fighter->Animator, "Direction");
CustomAnimator.GetBoolean(&fighter->Animator, "Speed");

// Setters
CustomAnimator.SetBoolean(&fighter->Animator, "Defending", true);
CustomAnimator.SetInteger(&fighter->Animator, "Direction", 25);
CustomAnimator.SetFixedPoint(&fighter->Animator, "Speed", FP._1);
  • 重要な留意点として、ここでは Unityのトリガーパラメータ がブーリアンのように作用します。つまり、パラメータをトリガーするのに、SetBoolean(&fighter→Animator, "MyTrigger", true)を使用してtrueに設定し、次のティックでSetBoolean(&fighter→Animator, "MyTrigger", false)を設定しトリガーが再度有効化しないようにする必要があります。各トリガーパラメータを毎ティックごとにfalseに設定するプレアニメーションシステムもあります。;

  • CustomAnimator.qtnファイルで以下の配列のサイズを変えることで カスタムアニメータがサポートしているパラメータの量を増やすことが できます。

C#

array<CustomAnimatorRuntimeVariable>[8] AnimatorVariables;
  • AnimatorStateにはカスタムアセットにリファレンスを作成できるAssetRefがあります。Unityのアニメータから情報を多く引っ張り、Unityのベイキングプロセスを拡張することも、これらの情報をカスタムアセットに保存してステート上で参照することも可能なので、シミュレーションで読み取ることができます。例えば、FPAnimationCurvesの形式でベイクされたhitbox・hurtbox情報をもつアセットを作成できます。Unityイベントの名前・時間をアセットに保存できるため、シュミレーション上でアニメーションイベントがいつ発生するかなど把握することができます。;

  • 自分のSystemSetup.csファイルで、以下の置換を行います。:

C#

// Old
new Core.AnimatorSystem(),

// New
new CustomAnimatorSystem(),
  • Unityで、コンテキストメニューCreate/Quantum/CustomAnimatorGraphからカスタムアニメータグラフアセットを作成します。

デフォルトステートでは以下の様な構成になっています。:

Custom Animator Default
  • Controllerフィールドを使用してUnityのAnimator Controllerアセットを参照し、Import Mecanim Controllerボタンをたたきます。それから、ステート、移動、パラメータなどのアニメーション情報フィールドを確認してください。:
Custom Animator Baked
  • EntityPrefabRootクラスを開き、public CustomQuantumAnimator CustomQuantumAnimator;フィールドを追加します。置換が目的ですので、希望する場合はQuantumAnimatorフィールドを削除することもできます。;
    PS: このファイルは、Quantumのバージョンアップグレードで上書きされる可能性があります。必要に応じてカスタムコードは再度挿入するようにしてください。

  • アニメーション化するGameObjectsにCustomQuantumAnimatorコンポーネントを追加します。もちろん、EntityPrefabRootは必要なので追加したコンポーネントへの参照を、上記の説明で作成したフィールドを使用して作成してください。;

Custom Animator Baked
  • On your EntityPrefabViewUpdaterに、Animatorコンポーネントを既定のエンティティから受け取る行がありますが、ここが代わりにCustomAnimatorを検索するようになりました。そのため、行の入れ替えを行います。:

C#

// Old
if (instance.QuantumAnimator) {
  var animator = Entity.GetAnimator(entity);
  if (animator != null) {
    instance.QuantumAnimator.Animate(animator);
  }
}

// New
if (instance.CustomQuantumAnimator) {
  var animator = Entity.GetCustomAnimator(entity);
  if (animator != null) {
    instance.CustomQuantumAnimator.Animate(animator);
  }
}
  • 最後に、UnityのAnimatorコンポーネントを自分のオブジェクトに追加します。EntityPrefabRootのある同じオブジェクトに配置されるか、子オブジェクトに配置される可能性もあります。:
Custom Animator Baked

quantumコードでの置換が完了したので、今度はUnityサイドで置換を行います。Unityのmecanim controllerから直接ベイクした、情報を持つCustomAnimatorGraphもあります。準備が整いました。

コードの一部には簡単なコメントが付けられています。Quantumサイドには、AnimatorConditionsなど内部ステートマシンそのものに関連するものすべてがあります。AnimatorConditionsはAnimatorTransitions、AnimatorVariables (パラメータ)、Layers、Motionsなどで使用されています。

Unityサイドでは、Custom Animator Graphアセットのカスタムエディタの描写に関連するコードとベイキング手順の処理を行うすべてのコード(これは今後より多くのデータを衝突情報のFPAnimationCurves、Unityのアニメーションイベントなどのアニメータアセットにベイクするために確実に拡張することになります)があります。

既知の問題

CustomAnimatorにはデフォルトで以下の通り挙げる既知の制限があります。

  1. 階層ステートサポートなし;
  2. Unityのアニメーションイベントサポートなし;
  3. モーションを持たない(アニメーションクリップがない)ステートに対するサポートなし;
  4. Layersメニューのサポートなし、つまりAvatar MasksやBlendingなど複数レイヤー間でのアニメーションの融合は不可能;
Back to top