Iris フィルタリング システム は、どのオブジェクトをどの接続にレプリケートするかを決定します。ゲーム内で、特定の接続にのみレプリケートしたいアクタやオブジェクトがある場合があります。時間と帯域幅を節約するために、このフィルタリング システムでは、アクタやオブジェクトをレプリケートできる接続をフィルタリングします。フィルタリング システムは、次の 4 種類のフィルタリングをサポートしています。
- オーナー:オブジェクトがオーナーと同じ接続にレプリケートされます。
- 接続:オブジェクトが指定の許可された接続にレプリケートされ、指定の許可されていない接続にはレプリケートされません。
- グループ:オブジェクトがそのグループ内の他のすべてのオブジェクトと同じ接続にレプリケートされます。
- 動的:オブジェクトがカスタムの動的フィルタリングに基づいてレプリケートされます。
オーナー
bOnlyRelevantToOwner フラグが true に設定されているアクタでは、オーナー フィルタリングが自動的に有効になります。アクタ以外のスタンドアローン オブジェクトでオーナー フィルタリングを有効にすることもできます。
オブジェクトでオーナー フィルタを設定する
アクタ以外のオブジェクトでオーナー フィルタリングを有効にするには、以下の手順を実行します。
-
レプリケートされたオブジェクトの
FNetRefHandleを取得します。Iris はこの識別子を使用して、レプリケーション システム内でオブジェクトの位置を特定します。#if UE_WITH_IRIS #include "Net/Iris/ReplicationSystem/ReplicationSystemUtil.h" #include "Net/Iris/ReplicationSystem/Filtering/NetObjectFilter.h" #endif UE_WITH_IRIS // 有効なレプリケートされたオブジェクトのポインタが含まれる場合 FNetRefHandle ObjectHandle = UE::Net::FReplicationSystemUtil::GetNetHandle(RepActorPtr); -
オブジェクトのレプリケートを担うレプリケーション システムへの参照を取得します。
UReplicationSystem* ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(RepActorPtr); -
レプリケートされたオブジェクトのオーナー フィルタ ハンドルを設定します。
ReplicationSystem->SetFilter(ObjectNetHandle, UE::Net::ToOwnerFilterHandle);
オーナー フィルタは、オブジェクトのオーナーが割り当てられた直後に割り当てる必要があります。
すべてのフィルタをクリアする
レプリケートされたオブジェクトのすべてのフィルタをクリアするには、まず オブジェクトのオーナー フィルタを設定する のステップ 1 と 2 を実行してから、フィルタを以下の特別なフィルタ ハンドルを使用するように設定します。
#if UE_WITH_IRIS
#include "Net/Iris/ReplicationSystem/ReplicationSystemUtil.h"
#include "Net/Iris/ReplicationSystem/Filtering/NetObjectFilter.h"
#endif UE_WITH_IRIS
UReplicationSystem* ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(RepActorPtr);
UE::Net::FNetRefHandle ObjectNetHandle = UE::Net::FReplicationSystemUtil::GetNetHandle(RepActorPtr);
// 特別な無効なハンドルにフィルタを設定する
ReplicationSystem->SetFilter(ObjectNetHandle, UE::Net::InvalidNetObjectFilterHandle);
接続
接続 ID を指定することで、オブジェクトがレプリケートされる接続を設定できます。このオプションは、次の場合に使用することをお勧めします。
- 当該オブジェクトに許可されている接続が静的である。さらに...
- 接続 ID が何らかの理由で変更された場合、影響を受けるのは少数のオブジェクトのみである。
多数のオブジェクトが影響を受ける可能性がある場合は、代わりにグループ フィルタリングの使用を検討してください。接続フィルタリングを使用すると、オブジェクトに許可されたまたは許可されていない接続を追加できます。
接続フィルタを設定する
許可された接続を追加するには、次の手順を実行します。
- オブジェクトのレプリケートを許可するすべての接続のビットを設定します。
-
接続フィルタを設定する前に、許可される接続の最大数で接続を初期化します。
#if UE_WITH_IRIS #include "Net/Iris/ReplicationSystem/ReplicationSystemUtil.h" #include "Net/Iris/ReplicaitonSystem/Filtering/NetObjectFilter.h" #endif UE_WITH_IRIS UReplicationSystem* ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(RepActorPtr); UE::Net::FNetRefHandle ObjectNetHandle = UE::Net::FReplicationSystemUtil::GetNetHandle(RepActorPtr); TBitArray<> Connections; Connections.Init(false, MaxConnectionCount); UNetConnection* ConnId = PlayerControllerPtr->GetNetConnection(); Connections.SetBit(ConnId); ReplicationSystem->SetConnectionFilter(ObjectNetHandle, Connections, UE::Net::ENetFilterStatus::Allow);
同様のロジックが、許可されない接続を追加する場合にも適用されます。ENetFilterStatus::Allow を使用する代わりに、ENetFilterStatus::Disallow 値を使用します。この場合、指定された接続は、オブジェクトのレプリケート先として許可されない接続となります。
接続フィルタをクリアする
オブジェクトに対する接続フィルタのクリアは、オーナー フィルタとは異なります。オブジェクトの接続フィルタをクリアするには、許可されない接続フィルタを設定します。ただし、指定された接続で許可しない接続は指定しません。
#if UE_WITH_IRIS
#include "Net/Iris/ReplicationSystem/ReplicationSystemUtil.h"
#include "Net/Iris/ReplicationSystem/Filtering/NetObjectFilter.h"
#endif UE_WITH_IRIS
TBitArray<> NoConnections;
UReplicationSystem* ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(RepActorPtr);
UE::Net::FNetRefHandle ObjectNetHandle = UE::Net::FReplicationSystemUtil::GetNetHandle(RepActorPtr);
ReplicationSystem->SetConnectionFilter(ObjectNetHandle, NoConnections, UE::Net::ENetFilterStatus::Disallow);
グループ
Iris には、グループを作成してそのグループに含まれるオブジェクトを管理するための API があります。グループをフィルタリングの仕組みとして使用することもできます。これは、どのオブジェクトがどのグループに属しているかを手動で管理する必要なく、一連のオブジェクトをレプリケートできる接続を柔軟に変更できる方法です。このユースケースの例には、以下に基づくフィルタリングがあります。
- チーム
- スクワッド
- ストリーミング レベル
オブジェクトは複数のグループに属することができます。レプリケーション対象として検討するオブジェクトのフィルタリング システムにグループを追加する必要があります。グループを追加すると、グループのどの接続メンバーをレプリケートできるかを変更できます。以下へのレプリケーションを許可するグループと許可しないグループを設定することができます。
- 単一の接続
- 接続のセット
- すべての接続
グループを作成する
フィルタ グループを作成するには、一意のグループ ハンドルを返す CreateGroup 関数を呼び出します。
#if UE_WITH_IRIS
#include "Net/Iris/ReplicationSystem/ReplicationSystemUtil.h"
#endif UE_WITH_IRIS
UReplicationSystem* ReplicationSystem = UE::Net::FReplicationSystemUtil::GetReplicationSystem(RepActorPtr);
FNetObjectGroupHandle GroupHandle = ReplicationSystem->CreateGroup();
グループ フィルタを追加する
フィルタ ステータスを設定して、オブジェクトを追加する前に、フィルタリング システムにグループ フィルタを追加する必要があります。
#if UE_WITH_IRIS
#include "Net/Iris/ReplicationSystem/ReplicationSystemUtil.h"
#endif UE_WITH_IRIS
// 有効な FNetObjectGroupHandle を追加する
ReplicationSystem->AddGroupFilter(GroupHandle);
グループ フィルタリングを設定する
グループを作成し、レプリケーション システムにグループ フィルタを追加したら、グループ フィルタリングを設定できます。この例では、ハンドル GroupHandle を持つグループに属する任意のオブジェクトは、ID SpecialConnectionId を持つ接続にのみレプリケートが許可されます。
#if UE_WITH_IRIS
#include "Net/Iris/ReplicationSystem/Filtering/NetObjectFilter.h"
#endif UE_WITH_IRIS
// 有効な FNetObjectGroupHandle と UNetConnection* がある場合
ReplicationSystem->SetGroupFilterStatus(GroupHandle, SpecialConnectionId, UE::Net::ENetFilterStatus::Allow);
オブジェクトをグループに追加する
これで目的のオブジェクトをグループに追加できます。
#if UE_WITH_IRIS
#include "Net/Iris/ReplicationSystem/Filtering/NetObjectFilter.h"
#endif UE_WITH_IRIS
// 有効な FNetObjectGroupHandle と FNetHandle がある場合
ReplicationSystem->AddToGroup(GroupHandle, ObjectNetHandle);
動的
Iris のフィルタリング システムは、UNetObjectFilter の派生クラスを使用してカスタムの動的フィルタリングを実装することもできます。動的フィルタは、カスタム ロジックに基づいてオブジェクトのレプリケートを制限できます。動的フィルタは、接続フィルタおよびグループ フィルタの後に適用されます。つまり、接続フィルタやグループ フィルタによってフィルタ済みのオブジェクトに対して、動的フィルタでレプリケーションを有効にすることはできません。オブジェクトには一度に 1 つの動的フィルタしか設定できません。
動的フィルタは常に 1 つのオブジェクトに対して実行されますが、接続フィルタおよびグループ フィルタはシステムに変更が通知されたときに限り実行されます。これは、動的フィルタはあらゆる方法で実装できるため、動的フィルタを実行する必要があるかどうかをシステムが把握する手段がないためです。動的フィルタの使用が適しているケースもあります。グループ間でアクタを移動したり、グループのレプリケート先の接続を変更したりするなど、グループを頻繁に変更する場合は、動的フィルタが最適なソリューションになります。
ただし、オブジェクトに動的フィルタを設定するのは、最終手段として使用してください。これを行うことで、接続フィルタやグループ フィルタに比べて CPU のオーバーヘッドが大きくなります。
UE では、「..\Engine\Source\Runtime\Experimental\Iris\Core\Public\Iris\ReplicationSystem\Filtering\」ディレクトリで動的フィルタを提供しています。
UFilterOutNetObjectFilter:追加されたオブジェクトのレプリケーションを許可しません。UNetObjectConnectionFilter:プレポーリング フィルタ。依存オブジェクトの接続ごとのフィルタリングをサポートします。UNetObjectGridFilter:ゲーム ワールドをセルに分割し、プレイヤーの視点に近いセルにのみオブジェクトをレプリケートします。
カスタムの動的フィルタを使用するには、UNetObjectFilter インターフェースを実装し、ランタイム時に使用できるようにフィルタ定義を設定する必要があります。
動的フィルタを作成する
カスタムの動的フィルタを使用するには、UNetObjectFilter インターフェースを実装し、ランタイム時にそのフィルタを使用するようにフィルタ定義を設定します。カスタム フィルタが継承する必要のある基本クラスは、以下のファイル パスにあります。
..\Engine\Source\Runtime\Experimental\Iris\Core\Public\Iris\ReplicationSystem\Filtering\NetObjectFilter.h
カスタムの動的フィルタの最小限の動作例は、以下のファイル パスにあります。
..\Engine\Source\Runtime\Experimental\Iris\Core\Public\Iris\ReplicationSystem\Filtering\NopNetObjectFilter.h
動的フィルタのコンフィギュレーション
以下に、カスタムの動的フィルタを使用するためのエンジンのコンフィギュレーションの構文を示します。
[/Script/IrisCore.NetObjectFilterDefinitions]
+NetObjectFilterDefintions=(FilterName=<FILTER_NAME>, ClassName=/Script/<PROJECT_NAME>.<FILTER_NAME>, ConfigClassName=/Script/<PROJECT_NAME>.<FILTER_NAME>Config)
たとえば、MyProject というプロジェクトの MyCustomFilter というカスタムの動的フィルタは、プロジェクトの「DefaultEngine.ini」ファイルなどの、エンジンのコンフィギュレーションの階層で下記のように設定されます。
[/Script/IrisCore.NetObjectFilterDefinitions]
+NetObjectFilterDefintions=(FilterName=MyCustomFilter, ClassName=/Script/MyProject.MyCustomFilter, ConfigClassName=/Script/MyProject.MyCustomFilterConfig)
フィルタを Iris に登録したら、プロジェクトの「DefaultEngine.ini」ファイルなどのエンジンのコンフィギュレーション ファイルで、以下のようにフィルタを設定することができます。
[/Script/MyProject.MyCustomFilterConfig]
MyCustomFilterVar=100
動的フィルタにオブジェクトを割り当てる
レプリケートされたオブジェクトに動的フィルタを割り当てるには、以下を使用します。
const UE::Net::FNetObjectFilterHandle FilterHandle = ReplicationSystem->GetFilterHandle(FName("<FILTER_NAME>"));
if (FilterHandle != UE::Net::InvalidNetObjectFilterHandle)
{
const bool bSuccess = ReplicationSystem->SetFilter(ObjectNetHandle, FilterHandle);
}
動的フィルタを削除する
動的フィルタは、オーナー フィルタと同じ方法で削除されます。任意のフィルタを削除するには、このページの「すべてのフィルタをクリアする」セクションを参照してください。