This document is about: FUSION 2
SWITCH TO

インタレストマネジメント

概要

インタレストマネジメントはデータカリングの機能で、サーバーから特定のクライアントへのデータ(ネットワークオブジェクトや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()を使用したプレイヤーのみが関心を持ちます
networkobject objectinterest options
Object Interestオプション

IInterestEnter / IInterestExit コールバック

ネットワークオブジェクトに登録されているコンポーネントにIInterestEnter/IInterestExitインターフェースを実装すると、ローカルプレイヤーがオブジェクトに対する関心を持った/失った時にInterestEnter(PlayerRef player)/InterestExit(PlayerRef player)が呼ばれます。これは、プレイヤーの関心領域にオブジェクトが出入りしたり、サーバーによって明示的にSetPlayerAlwaysInterested()が設定されたりした時に発生します。

これらのコールバックは、ホストモードのサーバー(専用サーバー/ホスト)でもトリガーされます。すべてのプレイヤーの関心から外れているネットワークオブジェクトの動作を、選択的に無効にするのに便利です(例えば、関心を持つプレイヤーがいないNPCのアニメーションを無効にしたい場合など)。

ローカルプレイヤーが関心を持つオブジェクトでのみ、クライアントでコールバックがトリガーされます。ホスト以外のプレイヤーは、他のプレイヤーがどのオブジェクトに関心を持っているかを知ることはできません。

NetworkBehaviourIInterestEnterIInterestExitの実装は、ネットワークオブジェクトによって自動的に検出されますが、NetworkBehaiourを継承しないコンポーネントでインターフェースを実装した場合は、NetworkRunnerに手動で登録する必要があります。

重要: プレイヤーの関心はSpawned()時に適用されるため、クライアントでは、オブジェクトがスポーンする時にIInterestEnterは呼び出されません。必要に応じて、Spawned()InterestEnter()固有の処理を実行してください。

重要: クライアントでは、オブジェクトがデスポーンする時にIInterestExitは呼び出されません。必要に応じて、Despawned()InterestExit()固有の処理を実行してください。

Area Of Interest

NetworkObjectでこのモードが選択されると、サーバーピア(共有モードを使用している場合は、共有サーバー)は、各プレイヤーが定義した関心領域(AOI)を使用して、プレイヤーがそのネットワークオブジェクトに関心があるかどうかを判定します。プレイヤーの関心領域を指定するには、Runner.AddPlayerAreaOfInterest()メソッドを呼び出します。

重要: 関心領域処理を有効にするには、Network Project ConfigReplication FeaturesScheduling and Interest Managementに設定する必要があります。

重要: Area Of Interest の処理を有効にするには、Network Project Config (NPC) の Replication Features フィールドを Scheduling and Interest Management に設定する必要があります。

enable interest management
NetworkProjectConfigからインタレストマネジメントを有効にする

重要: AddPlayerAreaOfInterest()で設定した領域が適用されるのは1ティックのみなので、状態権限を持つピアのFixedUpdateNetworkで、毎ティック領域を再適用する必要があります。

クライアントは、複数の領域を定義することができます(例えば、プレイヤーがリモートカメラを操作している場合など)。プレイヤーは、関心領域に1つ以上重なるネットワークオブジェクトに関心を持ち、サーバーからネットワークオブジェクトの更新を受け取ります。

NetworkTRSP要件

関心領域システムは、NetworkTRSPクラスの位置の値から、オブジェクトの位置を決定します。関心領域処理に含めたいネットワークオブジェクトは、NetworkObjectコンポーネントと同じゲームオブジェクトにNetworkTRSP派生クラスを追加する必要があります。

NetworkTRSPの詳細は、こちらをご覧ください。

以下のFusionのコンポーネントは、NetworkTRSPを継承していて、関心領域処理に準拠します。

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をご覧ください。

メインのNetworkTRSPAreaOfInterestOverrideを設定すると、サーバーは、別のネットワークオブジェクトの位置データを使用して、ネットワークオブジェクトに対するプレイヤーの関心を判定します。

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