インタレストマネジメント
概要
インタレストマネジメントは、サーバーから特定のクライアント/プレーヤーへの特定のネットワーク要素の更新を制限する、一連のデータカリング機能です。このカリングは、ネットワークトラフィックの削減や、データへのプレーヤーのアクセス制限(チームのみの情報など)に有効です。
データカリングの仕組みは、大きく分けて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のコンポーネントには以下があります。
NetworkPositionRotation
NetworkTransform
NetworkRigidbody
NetworkRigidbody2D
NetworkCharacterControllerPrototype
- アドバンスト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
に対するグループインタレストを明示的に割り当てられなければなりません。