Iris 優先順位付けシステム は、レプリケーション対象のアクタに優先順位を付けます。帯域幅に限りがあるため、レプリケートされたすべてのオブジェクトやプロパティがフレームごとに更新されるわけではありません。フレームごとにどのオブジェクトをレプリケートするのが最も重要かを決定するために、優先順位付けシステムは、オブジェクトやアクタに浮動小数点数の「レプリケーションの優先順位」を割り当てることで、ランク付けします。他のオブジェクトに対して優先順位が高いほど、オブジェクトがレプリケートされる可能性が高くなります。優先順位の範囲が異なると、オブジェクトがレプリケーション対象として考慮されるかどうかに対する影響も次のように異なります。
- 0.0 ~ 1.0 未満:オブジェクトは当該フレームではレプリケーション対象とはみなされません。
- 1.0 以上:更新され、レプリケートされたプロパティを含む場合、そのオブジェクトは当該フレームでレプリケーション対象とみなされます。
レプリケーションの優先順位は、オブジェクトがレプリケートされ、その優先順位がリセットされるまで、ネットワークのティックをまたいで累積されます。つまり、優先順位の低いオブジェクトでも、最終的には優先順位が高くなり、レプリケーションの対象になります。優先順位付けは、コードおよびデータのキャッシュ ミスを最小限に抑えるため、オブジェクトのバッチで行わされます。
Iris には、2 種類の優先順位付けがあります。
静的プライオリタイザ
静的プライオリタイザは、オブジェクトやアクタに一定の優先順位番号を割り当てます。オブジェクトに静的優先順位を割り当てるには、以下の手順を実行します。
-
レプリケートされたオブジェクトの
FNetRefHandleを取得します。Iris はこの識別子を使用して、レプリケーション システム内でオブジェクトの位置を特定します。#if UE_WITH_IRIS #include "Net/Iris/ReplicationSystem/ReplicationSystemUtil.h" #endif UE_WITH_IRIS // 有効なレプリケートされたオブジェクトのポインタが含まれる場合 FNetRefHandle ObjectHandle = UE::Net::FReplicationSystemUtil::GetNetHandle(RepActorPtr); -
オブジェクトのレプリケートを担うレプリケーション システムへの参照を取得します。
UReplicationSystem* ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(RepActorPtr); -
静的優先順位を使用するオブジェクトを設定します。
ReplicationSystem->SetStaticPriority(ObjectHandle, 1.0f);
動的プライオリタイザ
動的プライオリタイザは、選択したプライオリタイザによって定義されたロジックに応じて、オブジェクトまたはアクタに可変の優先順位番号を割り当てます。 Unreal Engine (UE) では、次の動的プライオリタイザを利用できます。
SphereNetObjectPrioritizerSphereWithOwnerBoostNetObjectPrioritizerNetObjectCountLimiter
ビルトインの動的プライオリタイザを選択するか、独自のプライオリタイザを作成することができます。独自の動的プライオリタイザを作成する方法については、「カスタムの動的プライオリタイザを作成する」を参照してください。
動的プライオリタイザを指定する
レプリケートされたオブジェクトに動的プライオリタイザを割り当てるには、次の手順を実行します。
-
レプリケートされたオブジェクトの
FNetRefHandleを取得します。#if UE_WITH_IRIS #include "Net/Iris/ReplicationSystem/ReplicationSystemUtil.h" #endif UE_WITH_IRIS // 有効なレプリケートされたオブジェクトのポインタが含まれる場合 FNetRefHandle ObjectHandle = UE::Net::FReplicationSystemUtil::GetNetHandle(RepActorPtr); -
オブジェクトのレプリケートを担うレプリケーション システムへの参照を取得します。
UReplicationSystem* ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(RepActorPtr); -
使用する動的プライオリタイザのハンドルを取得します。
// カスタムのプリオリタイザを使用するには、SphereNetObjectPrioritizer をカスタムのプリオリタイザの名前に置き換えます。 FNetObjectPrioritizerHandle PrioritizerHandle = ReplicationSystem->GetPrioritizerHandle(FName("SphereNetObjectPrioritizer"));カスタムの動的プリオリタイザを使用する予定がある場合は、プリオリタイザが「
DefaultEngine.ini」ファイルで設定されていることを確認してください。詳細については、「カスタム動的プライオリタイザを設定する」を参照してください。 -
動的プライオリタイザを使用するようにオブジェクトを割り当てます。
if (!ReplicationSystem->SetPrioritizer(ObjectHandle, PrioritizerHandle)) { UE_LOG(LogTemp, Warning, TEXT("Failed to assign dynamic prioritizer.")); // 動的プライオリタイザの割り当てに失敗した場合のために、フォールバック静的優先度を割り当てます。 ReplicationSystem->SetStaticPriority(ObjectHandle, 1.0f); }
提供される動的プライオリタイザの参照
球体プライオリタイザ
この動的プライオリタイザは、レプリケートされたワールド位置を含むすべてのアクタがデフォルトで使用します。このプライオリタイザは、有限の半径を持つ 2 つの同心球として表すことができます。
- 最も優先順位が高いのは、内部の球体内にあるオブジェクトです。
- 内部の球体の外側であるものの、外部の球体の内側にあるオブジェクトは、その位置に基づいた動的な優先順位を持ちます。
- 外部の球体の外側にあるオブジェクトの優先順位は最も低くなります。
見ている人を基準とした空間内のオブジェクトの球体プライオリタイザの視覚化。
以下に、球体プライオリタイザの仕組みの詳細について説明します。見ている人 (プレイヤー) は中央に表示されます。オブジェクトは、見ている人を基準としてどの位置にあるかによって優先順位が付けられます。内部の球体内にあるオブジェクトの優先順位は内部の優先順位です。外部の球体の外側にあるオブジェクトの優先順位は外部の優先順位です。内部の球体と外部の球体の間に位置するオブジェクトは、オブジェクトと見ている人の間の距離の 2 乗によって低下する可変の優先順位を持ちます。
これらの視覚化で使用されている色は、以下を示します。
- 緑:内部の優先順位
- 黄:外部の優先順位
- 赤:外側の優先順位
次の勾配表面プロットは、原点に位置する見ている人を基準とした位置の関数としてのオブジェクトの優先順位を示します。
同じ XY 平面上の見ている人を基準とした位置の関数としてのオブジェクトの優先順位。赤は外側の優先順位、黄色は外部の優先順位、緑は内部の優先順位に相当します。
球体プライオリタイザを設定する
SphereNetObjectPrioritizer は、「DefaultEngine.ini」などのエンジンのコンフィギュレーション ファイルで設定できます。
[Script/Iris.SphereNetObjectPrioritizerConfig]
InnerRadius=<INNER_RADIUS>
OuterRadius=<OUTER_RADIUS>
InnerPriority=<INNER_PRIORITY>
OuterPriority=<OUTER_PRIORITY>
OutsidePriority=<OUTSIDE_PRIORITY>
たとえば、デフォルトのコンフィギュレーション設定は、次のとおりです。
[Script/Iris.SphereNetObjectPrioritizerConfig]
InnerRadius=1000.0
OuterRadius=5000.0
InnerPriority=1.0
OuterPriority=0.2
OutsidePriority=0.1
オーナー ブースト付き球体プライオリタイザ
SphereWithOwnerBoostNetObjectPrioritizer は 球体プライオリタイザ と同じであるものの、所有する接続の優先順位を高めます。この場合、プライオリタイザは、球体プライオリタイザによって通常計算される優先順位に OwnerPriorityBoost の値を加算します。
オーナー ブースト付き球体プライオリタイザを設定する
SphereWithOwnerBoostNetObjectPrioritizer は、「DefaultEngine.ini」などのエンジンのコンフィギュレーション ファイルで設定できます。
[Script/Iris.SphereWithOwnerBoostNetObjectPrioritizerConfig]
InnerRadius=<INNER_RADIUS>
OuterRadius=<OUTER_RADIUS>
OwnerPriorityBoost=<OWNER_BOOST_PRIORITY>
InnerPriority=<INNER_PRIORITY>
OuterPriority=<OUTER_PRIORITY>
OutsidePriority=<OUTSIDE_PRIORITY>
オブジェクト数リミッター
NetObjectCountLimiter は、各フレームでレプリケーションの対象となるオブジェクトの数を制限します。
オブジェクト数リミッターを設定する
NetObjectCountLimiter は、「DefaultEngine.ini」などのエンジンのコンフィギュレーション ファイルで設定できます。
[Script/Iris.NetObjectCountLimiterConfig]
MaxObjectCount=<MAX_COUNT>
Priority=<PRIORITY>
OwningConnectionPriority=<OWNER_PRIORITY>
bEnableOwnedObjectsFastLane=[true | false]
たとえば、デフォルトのコンフィギュレーション設定は、次のとおりです。
[Script/Iris.NetObjectCountLimiterConfig]
MaxObjectCount=2
Priority=1.0
OwningConnectionPriority=1.0
bEnableOwnedObjectsFastLane=true
カスタムの動的プライオリタイザを作成する
次のディレクトリにある UNetObjectPrioritizer インターフェースを実装することで、カスタムの動的プライオリタイザを作成できます。
..\Engine\Source\Runtime\Experimental\Iris\Core\Public\Iris\ReplicationSystem\Prioritization\NetObjectPrioritizer.h
カスタムの動的プライオリタイザを設定する
カスタムのプライオリタイザをレプリケーション システムに登録するには、エンジンのコンフィギュレーション ファイルの階層 (プロジェクトの「DefaultEngine.ini」ファイルが望ましい) でプライオリタイザを設定する必要があります。
[/Script/IrisCore.NetObjectPrioritizerDefinitions]
+NetObjectPrioritizerDefinitions=(PrioritizerName=<PRIORITIZER_NAME>, ClassName=/Script/<MODULE_NAME>.<PRIORITIZER_NAME>, ConfigClassName=/Script/<CONFIG_MODULE_NAME>.<PRIORITIZER_CONFIG_NAME>)
構成要素:
PRIORITIZER_NAMEは、カスタムのプライオリタイザの名前です。MODULE_NAMEは、プライオリタイザが定義されているモジュールの名前です。CONFIG_MODULE_NAMEは、プライオリタイザが関連付けられているコンフィギュレーションが定義されているモジュールの名前です。PRIORITZER_CONFIG_NAMEは、カスタムのプライオリタイザのコンフィギュレーション クラスの名前です。
特殊な DefaultPrioritizer があります。設定されている場合、有効な WorldLocation を持つすべてのオブジェクトでこれが自動的に使用されます。
カスタムの動的プライオリタイザを使用する
レプリケートされたオブジェクトにカスタムの動的プライオリタイザを使用するには、動的プライオリタイザを指定する の手順を実行し、ステップ 3 の GetPrioritizerHandle の呼び出しでプライオリタイザの名前を使用します。