インタレストマネジメント
概要
インタレストマネジメントは、サーバーから特定のクライアント/プレーヤーへの特定のネットワーク要素の更新を制限する、一連のデータカリング機能です。このカリングは、ネットワークトラフィックの削減や、データへのプレーヤーのアクセス制限(チームのみの情報など)に有効です。
データカリングの仕組みは、大きく分けて2つあります。
- Object Interest: サーバーからの
NetworkObjectの更新を、特定のPlayerRefに制限する。 - Interest Groups: サーバーからの特定のネットワークプロパティの更新を、
PlayerRefごと /NetworkObjectごとに制限する。
オブジェクトインタレスト(Object Interest)
オブジェクトインタレストは、どのプレイヤーがサーバーからどのNetworkObjectの更新(Networked PropertiesとRPC)を受け取るかを決定します。
NetworkObject.ObjectInterest設定は、そのオブジェクトのプレイヤーインタレストをどのように決定するかをコントロールします。3つのモードオプションがあります。
- Area Of Interest: 3D空間でこのオブジェクトの
AoiPositionSourceと重なるAOI領域を持つプレイヤーのみが、このオブジェクトに興味を持つことになる。 - All Players: すべてのプレーヤーがこのオブジェクトのアップデートを受け取る。
- Explicit Players: 明示的にフラグを立てたプレイヤーのみが、このオブジェクトに興味を持つことになる。
Area Of Interest(関心領域)
サーバは各プレイヤーの AOI (Area Of Interest) リージョンを使用して、この NetworkObjectがそのプレイヤーにとって関心のあるものであるかどうかを判断します。プレイヤーのAOIリージョンはRunner.AddPlayerAreaOfInterest()メソッドを呼び出すことで指定します。
これらのリージョンは1ティック分しか存在しないので、1ティックごとに再適用する必要があります。プレイヤーは複数のリージョンを持つことができます(例えば、プレイヤーがリモートカメラを操作している場合など)。この NetworkObjectがプレイヤーのAOIリ―ジョンの 1 つ以上に含まれている場合、そのプレイヤーはこの NetworkObject に興味を持ち、サーバーの更新を受け取ることになります。
AoiPositionSource は、ゲームサーバーが NetworkObject のワールド空間での位置を決定するために、どの NetworkAreaOfInterestBehaviour派生コンポーネントが使用されるかを指定します。もしnullならば、NetworkObjectは実行時に NetworkAreaOfInterestBehaviourを探します。
NetworkAreaOfInterestBehaviourから派生するFusionのコンポーネントには以下があります。
NetworkPositionRotationNetworkTransformNetworkRigidbodyNetworkRigidbody2DNetworkCharacterControllerPrototype- アドバンストKCCアドオン
C#
public class SetAreaOfInterest : NetworkBehaviour
{
public float Extents = 32f;
public override void FixedUpdateNetwork()
{
if (Runner.IsServer)
{
var controller = Object.InputAuthority;
// Set the controlling players area of interest region around this object
if (controller)
{
Runner.AddPlayerAreaOfInterest(controller, transform.position, Extents);
}
}
}
}
備考: Object.SetPlayerAlwaysInterested()またはRunner.SetPlayerAlwaysInterested()は、AOIに加えて、AOIの範囲外であっても、強制的にオブジェクトに興味を持たせるために使用することができます。
備考: 現在、AOI範囲はエクステントであり、ワールド空間の X 軸と Z 軸のバウンディングボックスを定義しています。Y は AOI クエリでは無視されます。
All Players(全てのプレイヤー)
この NetworkObject は全てのプレイヤーにとって常に関心のあるものです。これは、この NetworkObject のオブジェクトカリングを効果的に無効にし、すべてのプレイヤーはこの NetworkObject のサーバーアップデートを受け取ります。
Explicit Players(明示的なプレイヤー)
この NetworkObject は、Runner.SetPlayerAlwaysInterested() でプレーヤーの関心を明確に追加しない限り、どのプレーヤーにとっても関心のあるものではありません。この NetworkObject のサーバアップデートは、明示的に関心を持ったプレイヤーのみが受け取ることができます。
C#
public class MakeAlwaysInterested : NetworkBehaviour, IPlayerJoined
{
void IPlayerJoined.PlayerJoined(PlayerRef player)
{
if (Runner.IsServer)
{
Object.SetPlayerAlwaysInterested(player, true);
// or
// Runner.SetPlayerAlwaysInterested(player, Object, true);
}
}
}
RPCとオブジェクトインタレスト
NetworkObjectのインスタンスにバインドされているため、Object Interestは静的でないRPCの配送にも影響を与えます。RpcInvokeInfoの戻り値は、RPCが接続されているNetworkObjectに興味のないプレイヤーに送信してします失敗を検出して処理するために、サーバ上で使用されます。
C#
[Rpc]
public RpcInvokeInfo RpcFoo()
{
return default;
}
public override void FixedUpdateNetwork()
{
if (Object.HasStateAuthority)
{
var info = RpcFoo();
int culledCount = info.SendResult.CulledReceivers.Length;
if (culledCount > 0)
{
//Handling for a target peer being culled from send
Debug.LogWarning($"{culledCount} receivers culled, possibly due to no Object Interest.");
}
}
}
インタレストグループ(Interest Groups)
Interest Groupsを使用して、Networked Propertyのアップデートを特定のプレイヤーのみに制限できます。
ネットワークプロパティは、指定されたインタレストグループに割り当てることができ、サーバは、これらのプロパティの更新を、このNetworkObjectに対するその指定されたインタレストグループに関心を持つプレーヤにのみ送信します(プレイヤーインタレストグループの割り当てはNetworkObjectごとであり、グローバルではありません)。
備考:Object InterestのためにNetworkObjectが更新を受信していない場合、インタレストグループに関係なく、メンバーデータも更新されません。
グループにプレイヤーインタレストを追加・削除する
インタレストグループに割り当てられたネットワークプロパティは、デフォルトではプレイヤーに複製されません。NetworkObjectのインタレストグループにプレイヤーインタレストを割り当てるには2つの方法があります。
-Explicitly Setting Player Interest(明示的にプレイヤーの関心を設定する):このNetworkObjectの特定のグループにPlayerRefの関心を追加/削除する。
-Default Interest Groups(デフォルトのインタレストグループ):このNetworkObjectの特定のグループに関心があるすべてのプレイヤーを自動的に設定する。
Explicitly Setting Player Interest
グループへのプレイヤーインタレストは、Object.SetInterestGroup()またはRunner.SetInterestGroup()メソッドを使用して、NetworkObject単位で追加および削除されます。
C#
using Fusion;
using UnityEngine;
public class PropertyGroupsSample : NetworkBehaviour, IPlayerJoined
{
// This Networked Property is assigned to the group 'EvenOnly'
// Only players with interest in 'EvenOnly' get property updates
[Networked(group: "EvenOnly")]
Color SecretColor { get; set; }
public override void Spawned()
{
// Apply interest in this NetworkObject for existing players
foreach (var player in Runner.ActivePlayers) {
Object.SetInterestGroup(player, "EvenOnly", player % 2 == 0);
}
}
void IPlayerJoined.PlayerJoined(PlayerRef player)
{
if (Runner.IsServer) {
// Apply interest in this NetworkObject for any players who join late.
// Only even numbered Players will be included in the group.
Object.SetInterestGroup(player, "EvenOnly", player % 2 == 0);
// This can alternatively be called directly with the runner (same meaning)
//Runner.SetInterestGroup(Object, player, "EvenOnly", player % 2 == 0);
}
}
public override void FixedUpdateNetwork()
{
if (Object.HasStateAuthority)
{
SecretColor = Color.HSVToRGB((Runner.Tick / 20f) % 1f, 1f, 1f);
}
}
public override void Render()
{
GetComponent<Renderer>().material.color = SecretColor;
}
}
Default Interest Groups
参加するすべてのプレイヤーは、このNetworkObjectに対するこれらのグループへ明示的に関心を示すことで開始します。このリストにないグループに対しては、プレイヤーはメソッドObject.SetInterestGroup()またはRunner.SetInterestGroup()を使用して(上記の例に示すように)、このNetworkObjectに対するグループインタレストを明示的に割り当てられなければなりません。