Available in the Gaming / Industries Circle
quantum | v2 switch to V1  

Custom Animator

Level Advanced

目次

イントロダクション

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

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

アニメータはQuantum SDK 2.0バージョンのデフォルトの一部ではありません。ただし、SDK 1.2.xバージョンには搭載されていたものでした。このアニメータツールの強化をやめたのは現在Unityのmecanim上にある依存性のため と、このドキュメントが書かれた日までに、Unityがまだ新しい安定したアニメーションツールをローンチしていなかったためです。このツールをまだご使用になっている場合は、ゲームのアニメーションニーズに応じて改良する必要がある点にご注意ください。

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

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

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

トップに戻る
 

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

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

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

トップに戻る
 

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

  • コンポーネントを使用する: CustomAnimatorコンポーネントの新しいインスタンスを作成し、エンティティに追加します。コードによる追加でもUnityでEntity Prototypesを使用しても構いません。:
var customAnimator = new CustomAnimator();
f.Set(fighter, customAnimator);
  • Unityでは、CustomAnimatorGraphタイプのデータアセットを新しく作成します。このアセットはUnityのmecanim controllaerに関連する情報の蓄積を担います。カスタムアニメータを設定するのに Entity Prototypes を使用している場合は、ここのAnimatorGraphフィールドでアニメータグラフを参照できます。コードでアセットを探すには以下の方法を参照してください。

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

  • CustomAnimatorコンポーネントを初期化する: Entity Prototypesを使用しており、Unityで既にCustomAnimatorがどのCustomAnimatorGraphを使用するか上記のように定義している場合、初期化を行う必要はありません。CustomAnimatorSystemクラスで、Reactiveコールバックを使用して既に初期化されています。ただし、Entity Prototypeを使用してコンポーネントを定義していない場合、またグラフアセットを選択していない場合は、以下の様にアセットを検索してアニメータに追加します。:
CustomAnimator.SetCustomAnimatorGraph(&knight->CustomAnimator, animatorGraphAsset);
f.Set(fighter, customAnimator);
  • Unityと同様アニメータに読み取り・書き込みを行うには、GettersとSettersを使用します。
// 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ファイル上で、自分のシステムの後に以下の行を挿入します。:

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

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

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

       public CustomQuantumAnimator CustomQuantumAnimator;
     **PS:** このファイルは、Quantumのバージョンアップグレードで上書きされる可能性があります。必要に応じてカスタムコードは再度挿入するようにしてください。
    
  • アニメーション化するGameObjectsにCustomQuantumAnimatorコンポーネントを追加します。もちろん、EntityPrefabRootは必要なので追加したコンポーネントへの参照を、上記の説明で作成したフィールドを使用して作成してください。;

Custom Animator Game Object
  • EntitiyViewUpdaterクラスを開きます。OnUpdateViewメソッド上にアクティブビュー間を行き来するforeachループがあります。これにはカスタムアニメータアップデートが含まれているはずですので、foreachは以下の様な構造になっています。:
// 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.Current.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のアニメーションイベントなどのアニメータアセットにベイクするために確実に拡張することになります)があります。

トップに戻る
 

既知の問題点/制限事項

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

  1. 階層ステートサポートなし;
  2. Unityのアニメーションイベントサポートなし;
  3. モーションを持たない(アニメーションクリップがない)ステートに対するサポートなし;
  4. Layers設定上のAvatar Maskサポートなし
  5. Blend Treesを使用する場合、1Dと2DのBlend Treesの両方で、ブレンドの値を[-1, 1]の間に設定する必要があります。
  6. 3D Transforms/PhysicsBody の Root Motion をサポートしていません。

ドキュメントのトップへ戻る