This document is about: QUANTUM 3
SWITCH TO

エンティティビュー

はじめに

**QuantumEntityViews**は、QuantumのViewコンポーネントを介してEntitiesにリンクされています。これは、ビューを表すGameObjectへのAssetRefを含み、その特定のエンティティのためにインスタンス化されるべきです。UnityでQuantumEntityViewを持つエンティティプロトタイププレハブまたはシーンオブジェクトを設定する際、QuantumのViewコンポーネントはプロトタイプに自動的に記入されます。

**QuantumEntityViewUpdater**は、Unity内のすべてのエンティティのビュー側を処理する役割を担っており、シミュレーションからのデータに基づいて関連するエンティティのビューゲームオブジェクトを作成、破棄、更新します。QuantumEntityViewUpdaterスクリプトは、QuantumMapを含むすべてのシーンに追加する必要があります。

**QuantumEntityViewComponents**を使用して、個々のEntityViewsにビュー関連の機能を追加できます。詳細はEntity View Componentセクションを参照してください。

プール

デフォルトでは、QuantumEntityViewUpdaterはエンティティが作成されるたびに新しいQuantumEntityViewプレハブのインスタンスを作成し、それに応じてビューゲームオブジェクトを破棄します。

エンティティビューのプールを有効にするには、QuantumEntityViewUpdaterゲームオブジェクトにQuantumEntityViewPoolスクリプトを追加します。このプールはEVUとシームレスに連携し、IQuantumEntityViewPoolインターフェースを使用することでカスタム実装に置き換えることができます。

HidePooledObjectsInHierarchy トグルをオンにすると、プールされたオブジェクトにHideFlags.HideInHierarchyが設定されます
ResetGameObjectScale トグルをオンにすると、オブジェクトのローカルスケールが1にリセットされます
Precache Items オブジェクトはAwake()中にインスタンス化され、プール内で利用可能になります

QuantumのコールバックやイベントにサブスクライブしているEntityViewsは、以下のいずれかを確実に行う必要があります:

  • ゲームオブジェクトがプールに戻される前に、サブスクライブを解除する
  • 下記のようにonlyIfActiveAndEnabledパラメータを有効にする

C#

QuantumEvent.Subscribe<EventPlayerKilled>(this, OnKilled, onlyIfActiveAndEnabled: true);

バインドビヘイビア

UnityのQuantumEntityViewスクリプトには、Bind Behaviourというプロパティがあり、次のいずれかに設定できます:

  • Non Verified: ビューゲームオブジェクトは予測フレーム内で作成できます
  • Verified: ビューゲームオブジェクトは確認フレーム内でのみ作成できます

Non Verifiedを使用することは、エンティティのビューが高頻度でインスタンス化される場合や、ゲームプレイの反応時間メカニクスにより、できるだけ早くプレイヤーの画面に表示する必要がある場合に通常は推奨されます。例えば、高速で進行するシューティングゲームにおける弾丸の作成は、この選択肢を使用すべきです。

一方で、Verifiedは主に即座に表示する必要がないエンティティのビューに対して有用であり、確認フレームを待つための小さな遅延が許容できる場合に役立ちます。これは、ミス予測の間にビューオブジェクトを作成/破棄するのを避けるために使われることがあります。プレイ可能なキャラクターエンティティの作成の際に使用する良い例です。

マニュアル廃棄

Manual Disposalプロパティがオンの場合、QuantumEntityViewUpdaterの破壊メソッドはスキップされます。これにより、QuantumEntityViewOnEntityDestroyedコールバックを使用して手動で破棄することや、カスタム破棄イベントを介して破壊することが可能になります。

ビューフラグ

ビューフラグは、エンティティビューの詳細設定を行い、パフォーマンスの調整を可能にします。

| DisableUpdateView | QuantumEntityView.UpdateView()およびQuantumEntityView.LateUpdateView()は処理されず、エンティティビューコンポーネントに転送されません。 |

DisableUpdatePosition エンティティビューの位置更新を完全に無効にします。
UseCachedTransform Transformプロパティを呼び出さず、キャッシュされたトランスフォームを使用してパフォーマンスを向上させます。
DisableEntityRefNaming デフォルトでは、エンティティゲームオブジェクトはそのEntityRef値に似た名前が付けられます。このフラグを設定するとこの動作が無効になります。
DisableSearchChildrenForEntityViewComponents エンティティビューゲームオブジェクトの子オブジェクトからエンティティビューコンポーネントを検索することを無効にします。

予測エラー修正

エンティティビューのエラー修正設定を微調整します。各パラメータの詳細な説明は、Unityインスペクターに記載されています。

イベント

エンティティビューの作成(プールからの作成も含む)および破棄にUnityイベントを追加します。UnityEvent<QuantumGame>を使用します。

エンティティのテレポート

QuantumEntityViewスクリプトは、デフォルトでエンティティのGameObjectの視覚を補間します。これにより、シミュレーションレート、レンダーレートの違いや、ミス予測におけるエラー修正に対応します。

エンティティを1フレーム内で遠方の位置に移動させる(つまり「テレポート」する)と、シミュレーション内のエンティティデータはターゲット位置に即座にスナップしますが、ビューの補間は数フレームにわたって開始位置と終了位置の間を線形補間するため、視覚的に非常に速く動いているように見えることがあります。これは望ましくありません。

この問題を防ぐために、エンティティの位置が大きく変わる必要がある場合(通常、エンティティが再出現するか、ゲームにテレポート機能がある場合に移動する際)は、transform->Teleport(frame, newPosition);を使用します。これにより、エンティティビューコンポーネントは自動的に補間されない移動を適用します。

ビューの検索

特定のエンティティのビューを見つけるのは非常に一般的なユースケースです。シミュレーション側はQuantumEntityViewsの存在を認識していないため、EntityRefsはイベントを介してビューに渡すか、フレームからポーリング(読み取り専用)する必要があります。QuantumEntityViewUpdaterには、特定のEntityRefのビューを見つけるために使用できるGetView(EntityRef)関数があります。ビューは辞書にキャッシュされているため、検索は非常に効率的です。

イベントと更新順序

QuantumEntityViewUpdaterOnObservedGameUpdated関数は、EntityViewsの作成、破棄、更新を担当しており、イベントが処理される前に呼び出されます。これは、イベント内で破棄されたエンティティが、すでにそのビューを破棄している可能性があることを意味します。

カスタム破棄イベント

一般的なパターンとして、エンティティを破棄したいが、破棄に関する追加情報をビューに渡すイベントを実行したい場合があります。イベントが処理される前にQuantumEntityViewが破棄されないように、そのManual Disposalフィールドをtrueに設定します。

これにより、ビューは生存し続け、デフォルトでGameObjectを破棄するQuantumEntityViewUpdaterDestroyEntityViewInstance関数に渡されることはありません。

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

AutoFindMapData

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

カスタマイズ

QuantumEntityViewUpdaterは、以下のカスタマイズの可能性を提供します。

Createのオーバーライド

GameObjectsをインスタンス化するのではなく、プールから取得するには、CreateEntityViewInstance関数をオーバーライドします。この関数には、どのビューを生成するかを示すQuantum.EntityViewパラメータがあります。QuantumEntityView.AssetGuidを使用してプールされたオブジェクトの辞書のキーとして使うことができます。

C#

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

    // view pooling can also be customized by using IQuantumEntityViewPool
    EntityView view = _myObjectPool.GetInstance(asset);

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

    return view;
}

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

Destroyのオーバーライド

ビューを破棄するのではなく、プールに戻すには、DestroyEntityViewInstance()をオーバーライドします。

C#

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

マップエンティティ

マップエンティティの場合、ActivateMapEntityInstance()はビューをアクティブにする責任があり、必要に応じてカスタムの動作のためにオーバーライドすることができます。

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

Back to top