インタレストマネジメント
概要
インタレストマネジメントはデータカリングの機能で、サーバーから特定のクライアントへのデータ(ネットワークオブジェクトやNetworkBehaviour
)複製を制限します。これは、ネットワークトラフィックの削減や、プレイヤーのデータアクセス制限(同じチームのみに送る情報など)に役立ちます。
主要なデータカリングメカニズムは、以下の2つです。
- Object Interest: サーバーから特定の
PlayerRef
への、NetworkObject
の更新を制限する - Behaviour Interest: サーバーから特定の
PlayerRef
への、NetworkBehaviour
の更新を制限する
Object Interest
Object Interestはネットワークオブジェクトごとの設定で、オブジェクトに対して、プレイヤーがどのように関心を持つのかを定めます。ネットワークオブジェクトに関心を持たないプレイヤーは、サーバーからネットワークオブジェクトの更新(ネットワークプロパティやRPC)を受け取ることは一切ありません。
NetworkObject.ObjectInterest
には、以下の3つのオプションがあります。
- Area Of Interest:プレイヤーは、自身の関心領域と位置(2D/3D)が重なるネットワークオブジェクトに対して関心を持ちます
- Global:ネットワークオブジェクトに対して、すべてのプレイヤーが関心を持ちます
- Explicit:ネットワークオブジェクトに対して、明示的に
SetPlayerAlwaysInterested()
を使用したプレイヤーのみが関心を持ちます
IInterestEnter / IInterestExit コールバック
ネットワークオブジェクトに登録されているコンポーネントにIInterestEnter
/IInterestExit
インターフェースを実装すると、ローカルプレイヤーがオブジェクトに対する関心を持った/失った時にInterestEnter(PlayerRef player)
/InterestExit(PlayerRef player)
が呼ばれます。これは、プレイヤーの関心領域にオブジェクトが出入りしたり、サーバーによって明示的にSetPlayerAlwaysInterested()
が設定されたりした時に発生します。
これらのコールバックは、ホストモードのサーバー(専用サーバー/ホスト)でもトリガーされます。すべてのプレイヤーの関心から外れているネットワークオブジェクトの動作を、選択的に無効にするのに便利です(例えば、関心を持つプレイヤーがいないNPCのアニメーションを無効にしたい場合など)。
ローカルプレイヤーが関心を持つオブジェクトでのみ、クライアントでコールバックがトリガーされます。ホスト以外のプレイヤーは、他のプレイヤーがどのオブジェクトに関心を持っているかを知ることはできません。
NetworkBehaviour
のIInterestEnter
とIInterestExit
の実装は、ネットワークオブジェクトによって自動的に検出されますが、NetworkBehaiour
を継承しないコンポーネントでインターフェースを実装した場合は、NetworkRunner
に手動で登録する必要があります。
重要: プレイヤーの関心はSpawned()
時に適用されるため、クライアントでは、オブジェクトがスポーンする時にIInterestEnter
は呼び出されません。必要に応じて、Spawned()
でInterestEnter()
固有の処理を実行してください。
重要: クライアントでは、オブジェクトがデスポーンする時にIInterestExit
は呼び出されません。必要に応じて、Despawned()
でInterestExit()
固有の処理を実行してください。
Area Of Interest
NetworkObject
でこのモードが選択されると、サーバーピア(共有モードを使用している場合は、共有サーバー)クラウドサーバーは、各プレイヤーが定義した関心領域(AOI)を使用して、プレイヤーがそのネットワークオブジェクトに関心があるかどうかを判定します。プレイヤーの関心領域を指定するには、Runner.AddPlayerAreaOfInterest()
メソッドを呼び出します。
重要: 関心領域処理を有効にするには、Network Project Config
のReplication Features
をScheduling and Interest Management
に設定する必要があります。
重要: Area Of Interest の処理を有効にするには、Network Project Config (NPC) の Replication Features
フィールドを Scheduling and Interest Management
に設定する必要があります。
重要: AddPlayerAreaOfInterest()
で設定した領域が適用されるのは1ティックのみなので、FixedUpdateNetwork
で毎ティック、領域を再適用する必要があります。
クライアントは、複数の領域を定義することができます(例えば、プレイヤーがリモートカメラを操作している場合など)。プレイヤーは、関心領域に1つ以上重なるネットワークオブジェクトに関心を持ち、サーバーからネットワークオブジェクトの更新を受け取ります。
NetworkTRSP要件
関心領域システムは、NetworkTRSP
クラスの位置の値から、オブジェクトの位置を決定します。関心領域処理に含めたいネットワークオブジェクトは、NetworkObject
コンポーネントと同じゲームオブジェクトにNetworkTRSP
派生クラスを追加する必要があります。
NetworkTRSP
の詳細は、こちらをご覧ください。
以下のFusionのコンポーネントは、NetworkTRSP
を継承していて、関心領域処理に準拠します。
NetworkTransform
NetworkRigidbody3D
(Unity Physics Addon)NetworkRigidbody2D
(Unity Physics Addon)NetworkCharacterControllerPrototype
- The Advanced KCC アドオン
AddPlayerAreaOfInterestの使用方法
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.IsNone)
{
Runner.AddPlayerAreaOfInterest(controller, transform.position, Extents);
}
}
}
}
備考: Object.SetPlayerAlwaysInterested()
/Runner.SetPlayerAlwaysInterested()
を関心領域と合わせて使用することで、関心領域外のオブジェクトに対して強制的に関心を持たせることができます。
AreaOfInterestOverride
NetworkTransformのAreaOfInterestOverrideをご覧ください。
メインのNetworkTRSP
にAreaOfInterestOverride
を設定すると、サーバーは、別のネットワークオブジェクトの位置データを使用して、ネットワークオブジェクトに対するプレイヤーの関心を判定します。
C#
public void ChangeAOIOverride(NetworkObject proxyObject)
{
// Any NetworkTRSP derived component (such as NetworkTransform)
// on the root of an NetworkObject is referred to as the Main TRSP,
// This main NetworkTRSP component is used to determine AOI for the NetworkObject.
var mainTRSP = Object.GetComponent<NetworkTRSP>();
// Setting AreaOfInterestOverride on the main NetworkTRSP tells Fusion to use the
// Area Of Interest results of different NetworkObject to determine this Object's Interest.
// Setting this to 'null' disables the override.
Object.GetComponent<NetworkTRSP>().SetAreaOfInterestOverride(proxyObject);
}
Global
すべてのプレイヤーが、このネットワークオブジェクトに対して関心を持ちます。ネットワークオブジェクトに対するカリングを効率的に無効化でき、すべてのプレイヤーが、ネットワークオブジェクトの更新をサーバーから受け取ります。
Explicit
Runner.SetPlayerAlwaysInterested()
で明示的に関心を持ったプレイヤーのみが、このネットワークオブジェクトに対して関心を持ちます。明示的に関心を持ったプレイヤーのみが、ネットワークオブジェクトの更新をサーバーから受け取ります。
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とObject Interest
Object Interestは、静的ではないRPC(インスタンスRPC・ターゲットRPC)の配信にも影響します。サーバーは、ネットワークオブジェクトに関心を持たないプレイヤーへのRPC送信の失敗を、RpcInvokeInfo
の戻り値から検知して処理できます。
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.");
}
}
}
Behaviour Interest
ホストモード(専用サーバー/ホスト/シングルプレイヤー)のサーバーピアは、NetworkBehaviour
のすべてのネットワークプロパティ(状態)の複製を、特定のプレイヤーのみに制限することができます。
ReplicateTo(PlayerRef player)
メソッドを独自実装でオーバーライドすると、状態を複製するかどうかをプレイヤーごとに選択できます。
備考: これはホストモードでのみ適用可能(共有モードでは不可能)です。また、ReplicateTo()
は、ホストモードのサーバー(状態権限を持つピア)でのみ有効です。
備考: Behaviour Interestより先にObject Interestが決定されます。ネットワークオブジェクトに関心を持たないプレイヤーは、そのオブジェクトのNetworkBehaviour
も複製されません。
備考: Behaviour Interestは、ネットワークプロパティ([Networked]
属性が付いたプロパティ)にのみ影響します。リモートプロシージャコール(RPC)には影響しません。
使用方法
C#
using Fusion;
public class InterestManagementSampleCode : NetworkBehaviour
{
// Because this NetworkBehaviour is restricted to even players by the ReplicateTo() override
// Only clients with an even LocalPlayer value will get updates for this value.
// For odd-numvered players this value will remain zero.
[Networked]
int secretNumberOnlyEvenPlayersShouldKnow { get; set;}
// NOTE: This method is only ever called on the Server in Server Mode
// and is not applicable to Shared Mode
protected override bool ReplicateTo(PlayerRef player)
{
// Only replicate this behaviours state to Players with even numbered PlayerIDs
return player.PlayerId % 2 == 0;
}
}
Back to top