This document is about: QUANTUM 2
SWITCH TO

Custom Animator

Level 4
Available in the Gaming Circle and Industries Circle
Circle

イントロダクション

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

これを使用する主な利点は、マシン間で100%同期するようにアニメーションを制御できることです。アニメーションは正しい状態にスナップし、予測ロールバックに従って時間をクリップします。そのため、非常に正確なティックベースのアニメーションを提供することができます。これは、すべてのクライアントシミュレーション間でアニメーションが完全に同期している必要があるため、格闘ゲームや一部のスポーツゲームで通常必要とされるものです。

このアドオンがUnityのMecanimに依存していることと、Unityに新しいアニメーションツールがないことから、アドオンの改善を中止することにしました。このツールを使用する場合、あなたのゲームのアニメーションの必要性に基づいて、チームがコードを変更する必要があるかもしれません。

そのため、アニメーターをオープンソースとして公開し、quantum.codeプロジェクトにインポートして変更できるようにしました。

このドキュメントではカスタムアニメータのインポート方法とプロジェクト内での使用方法について説明します。

こちらのパッケージはQuantum SDK 2.1.0 A1の夜間ビルド384で最後にテストを行いました。

既知の問題/制限

デフォルトのCustomAnimatorには、以下の既知の制限があります:

  1. 階層的な状態に対応していません
  2. Unityのアニメーションイベントに対応していません
  3. モーションのないステート(アニメーションクリップが設定されていない)に対応していません
  4. レイヤー(Layers) メニューに対応していません。つまり、アバターマスク(Avatar Masks)やブレンド(Blending)などを使用して、複数のレイヤー間でアニメーションを混ぜることができません
  5. ブレンドツリー(Blend Trees)を使用する場合、1Dと2Dの両方のブレンドツリー(Blend Trees)で、ブレンド値を[-1, 1]の間に設定する必要があります;
  6. 3D Transforms/PhysicsBodyのRoot Motionに対応していません。

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

  1. ここからカスタムアニメータをダウンロードします。;
  2. カスタムアニメータを解凍し、QuantumCustomAnimator_stateフォルダと QuantumCustomAnimator_systems フォルダのコンテンツをquantum.codeプロジェクトの任意の場所に入れます。;
  3. このパッケージにはFrame.InitUserメソッドの部分実装が搭載されています。このメソッドはCustomAnimatorUpdaterの初期化を処理します。既にプロジェクトに同メソッドの部分実装がある場合はInitUser内で忘れずにInitializeAnimatorUpdaterメソッドへの呼び出しを含めるようにしてください。そして、このパッケージからFrame.User.csファイルをインポートしないでください。;
  4. 自分のソリューションに全てそろったら、quantum.systemsソリューションをビルドします。;
  5. Unityで、プロジェクトにQuantumCustomAnimator.unitypackageファイルをインポートします。;

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

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

  • このコンポーネントを使用するには、Unity 上の Entity Prototype に直接追加します。また、CustomAnimatorコンポーネントの新しいインスタンスを作成し、コードで直接エンティティに追加することもできます:

C#

var customAnimator = new CustomAnimator();
f.Set(fighter, customAnimator);
  • Unity上で、CustomAnimatorGraph型の新しいデータアセットを作成します。これは Unity の Mecanim コントローラーに関連する情報を保存するアセットです。Entity Prototypes を使用してカスタムアニメーターを設定する場合、Inspector の AnimatorGraph フィールドで Animator Ggraph アセットを参照することができます。別の方法として、コードでグラフアセットを読み込むこともできます:

var animatorGraphAsset = f.FindAsset<CustomAnimatorGraph>(assetGuid);

  • CustomAnimatorコンポーネントの初期化:エンティティプロトタイプを使用し、上記のようにCustomAnimatorGraphを定義する場合、コンポーネントを初期化する必要はありません。しかし、コードで初期化することもできます:

C#

CustomAnimator.SetCustomAnimatorGraph(&knight->CustomAnimator, animatorGraphAsset);
f.Set(fighter, customAnimator);
  • Unityでのやり方と同様に、Animatorへの読み書きには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に設定するプレアニメーションシステムもあります。;

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

  • SystemSetup.csファイル上で、自分のシステムの後に以下の行を挿入します。:

C#

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

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

custom animator default
  • Controllerフィールドを使用してUnityのAnimator Controllerアセットを参照し、Import Mecanim Controllerボタンをたたきます。それから、ステート、移動、パラメータなどのアニメーション情報フィールドを確認してください。:
custom animator baked
  • EntityViewクラスを開き、以下のフィールドを追加します。:

    C#

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

custom animator game object
  • EntitiyViewUpdaterクラスを開きます。OnUpdateViewメソッド上にアクティブビュー間を行き来するforeachループがあります。これにはカスタムアニメータアップデートが含まれているはずですので、foreachは以下の様な構造になっています。:

C#

// Iterate over all view instances and update components using only entities from current frame.
foreach (var kvp in _activeViews) {
    // ... updates 2D and 3D transforms

    // At the end of the foreach, add this.
    // This is responsible for actually animating the entity views
    if (instance.CustomQuantumAnimator)
    {
        if (game.Frames.Predicted.Unsafe.TryGetPointer<CustomAnimator>(instance.EntityRef, out var animator))
        {
            instance.CustomQuantumAnimator.Animate(game.Frames.Current, animator);
        }
    }
}
  • 最後に、UnityのAnimatorコンポーネントを自分のオブジェクトに追加します。EntityPrefabRootのある同じオブジェクトに配置されるか、子オブジェクトに配置される可能性もあります。:
custom animator mecanim controller

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

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

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

Back to top