This document is about: QUANTUM 2
SWITCH TO

エンティティビュー

イントロ

EntityViewUpdaterEntityViewは、Unityのすべてのエンティティのビュー側の処理を担当します。これらのUnityコンポーネントは、シミュレーションからのデータに基づいて、エンティティのビューゲームオブジェクトの破壊、作成、更新などのロジックを実行します。EntityViewUpdaterMonoBehavoiurで、Mapを含むすべてのゲームシーンに存在する必要があります。

組み込みの実装はプロトタイピングや単純なユースケースには十分ですが、多くの場合はカスタム実装が必要になります。EntityViewUpdaterEntityViewの多くの関数は仮想関数であり、オーバーライドすることができます。また、実装を完全にカスタム実装に置き換えることもできます。EntityViewUpdaterEntityViewのソースはUnityプロジェクトで公開されています。

EntityViewsView Quantum コンポーネントを介して Entities にリンクされます。このコンポーネントにはエンティティ用にスポーンするビュー GameObject への AssetRef が含まれています。Unityで EntityPrototype プレハブやシーンオブジェクトに EntityView を設定すると、自動的に View コンポーネントが正しいビューでプロトタイプに保存されます。

EntityView Pooling

デフォルトでは、EntityViewUpdaterはエンティティが作成されるたびにEntityViewプレハブの新しいインスタンスを作成し、エンティティが破棄されるとビューのGameObjectをそれぞれ破棄します。これは特にモバイルプラットフォームではCPU負荷が高くなります。手動でビューをプールすることでGameObjectをプールし、パフォーマンスを向上させることができます。

作成のオーバーライド

GameObjectをインスタンス化する代わりにプールから取得するには、CreateEntityViewInstance関数をオーバーライドする。この関数には EntityViewAsset パラメータがあり、スポーンするビューを指定する。EntityView.AssetGuidはプールされたオブジェクトの辞書のキーとして使用することができます。

実装例

C#

protected override EntityView CreateEntityViewInstance(EntityViewAsset asset, Vector3? position = null, Quaternion? rotation = null) {
    Debug.Assert(asset.View != null);

    EntityView view = _myObjectPool.GetInstance(asset);

    view.transform.position = position ?? default;
    view.transform.rotation = rotation ?? Quaternion.identity;

    return view;
}

CreateEntityViewInstanceの結果は、OnEntityViewInstantiatedでEntityに割り当てられます。このメソッドも仮想メソッドでオーバーライドすることができますが、ほとんどの場合、オーバーライドする必要はありません。オーバーライドする場合は、EntityRef の割り当てを維持することが重要です。

デストロイのオーバーライド

ビューを破棄せずにプールに戻すには DestroyEntityViewInstance をオーバーライドします。

*実装例

C#

protected virtual void DestroyEntityViewInstance(EntityView instance) {
    _myObjectPool.ReturnInstance(instance);
}

マップエンティティ

マップエンティティでは ActivateMapEntityInstance がビューをアクティブにします。これはビューのアクティブ化を担当し、必要に応じてカスタム動作のためにオーバーライドできます。

DisableMapEntityInstanceはデフォルトでGameObjectを無効にするために呼ばれます。この関数はカスタムの動作のためにオーバーライドすることができます。

Manual Disposal

EntityView には Manual Disposal プロパティがあり、インスペクタで切り替えることができます。有効にすると EntityViewUpdater の破棄メソッドがスキップされます。これにより、 EntityViewOnEntityDestroyed コールバックを使用して手動で破棄したり、カスタムの破棄イベントを使用して破棄することができます。

エンティティビューの検索

非常に一般的なユースケースは、特定のエンティティのビューを見つけることです。シミュレーション側では EntityViews を認識できないため、イベント経由で EntityRef をビューに渡す必要があります。EnityViewUpdaterには GetView(EntityRef) 関数があり、これを使用してビューを見つけることができます。ビューは辞書にキャッシュされるので、検索は非常に効率的です。

イベントとEntityViewの更新順序

EntityViewの作成、破棄、更新を行う EntityViewUpdaterOnUpdateView 関数は、イベントが処理される前に呼び出されます。つまり、イベントの中で破壊されたエンティティは既にビューが破壊されている可能性があります。

カスタムでイベントを破棄

エンティティを破棄しても、破棄に関する追加情報を含むイベントをビューに実行したい場合 があります。イベントが処理される前に EntityView が破棄されないようにするには、EntityViewManual Disposal を true に設定します。

これにより、デフォルトではGameObjectを破壊する EntityViewUpdaterDestroyEntityViewInstance 関数に渡す代わりに EntityView を保持することができます。

それで、イベントハンドラはまだビューを見つけることができ、ビューが存在する状態でdestroyイベントを実行することができる。EntityViewは破棄するかオブジェクトプールに戻すかして手動でクリーンアップする必要があります。

AutoFindMapData

EntityViewを持つマップを使用する場合、AutoFindMapDataを有効にする必要があります。有効にすると、ビューは対応するMapDataオブジェクトを検索し、マップエンティティとそのビューをマッチさせます。MapDataコンポーネントが存在しないシーンを可能にするために、エンティティでマップを使用していない場合は、これを無効にしてください。

カスタム補間とテレポートエントリ

EntityView コンポーネントはデフォルトでエンティティ GameObject のビジュアルを補間します。これはシミュレーションレートとレンダリング(更新)レートの差を調整するため、および予測ミスのエラー修正のためです。

大きな距離でエンティティをテレポートする場合、この補間はビューをテレポートするのではなく、開始位置と終了位置の間でビューを補間します。この動作をオーバーライドするには、EntityViewを継承し、ApplyTransform関数をオーバーライドします。UpdatePostionParameterパラメータには、エンティティを表示するために必要なすべての情報が含まれます。param.UninterpolatedPositionparam.UninterpolatedRotationを使用して、カスタム補間を実装し、ビジュアルを正しく表示するためにテレポート中に補間されていない位置にスナップします。

さらに、すべてのエンティティの補間をリセットするために、EntityViewUpdaterにある TeleportAllEntities を使用することで、マップをリセットする際に、1フレームのすべてのエンティティの補間を無効にすることができます。

Back to top