Interest Management
概述
興趣管理 是一組資料剔除功能,它限制了特定網路物件和網路行為從伺服器到特定玩家客戶端的資料複製。這種剔除有助於減少網路流量,並限制玩家存取資料(如僅限團隊的資訊)。
有兩種主要的資料剔除機制:
物件興趣
物件興趣 是每個網路物件的設定,指示應如何確定玩家對該物件的興趣。對該網路物件不感興趣的玩家將不會從伺服器同儕節點接收到該物件的任何更新(已連網屬性以及RPC)。
有三個NetworkObject.ObjectInterest
選項:
- 興趣區域:AOI區域與此網路物件在2d/3d空間中的位置重疊的玩家,將對此物件感興趣。
- 全域:所有玩家都會收到此網路物件的更新。
- 明確:只有使用
SetPlayerAlwaysInterested()
明確標記的玩家才會對此網路物件感興趣。
IInterestEnter / IInterestExit回調
InterestEnter(PlayerRef player)
和InterestExit(PlayerRef player)
在網路物件的登錄元件上調用,這些元件在本機玩家對該物件感興趣或失去興趣時實作了IInterestEnter
和IInterestExit
介面。物件進入/退出玩家的某個興趣區域,或者伺服器明確設定SetPlayerAlwaysInterested()
,將獲得/失去興趣。
在伺服器/客戶端模式(專用伺服器/主機)下,這些回調也會在伺服器上觸發。如果當前所有玩家都不感興趣,這對於選擇性地停用伺服器上網路物件的某些方面非常有用(例如,當沒有玩家感興趣時,NPC可能希望停用動畫)。
此回調僅在客戶端上觸發與本機玩家相關的興趣更改。非主機玩家不知道其他玩家對物件感興趣。
網路物件將自動找到NetworkBehaviour
中的IInterestEnter
和IInterestExit
實作,但是具有這些介面的任何非NetworkBehaviour
衍生元件都需要手動向NetworkRunner
登錄。
重要: 當對象在客戶端上被生成時,不會調用IInterestEnter
,因為Spawned()
的發生暗示了玩家的興趣。您可能希望在Spawned()
中調用您的InterestEnter()
特定處理。
重要: 當對象在客戶端上被取消生成時,不會調用IInterestExit
。您可能希望在Despawned()
中調用您的InterestEnter()
特定處理。
興趣區域
當在NetworkObject
上選擇此物件興趣模式時,伺服器同儕節點(包括使用共享模式時的共享模式伺服器)將使用每個客戶端玩家定義的興趣區域(AOI)的區域來確定該玩家是否對該網路物件感興趣。玩家AOI區域是透過調用Runner.AddPlayerAreaOfInterest()
方法來指定的。
重要: 網路專案設置(NPC)中的Replication Features
欄位必須設定為Scheduling and Interest Management
,才能啟用興趣區域處理。
重要: 使用AddPlayerAreaOfInterest()
設定的區域只適用於一個刷新,並且需要在狀態授權同儕節點的FixedUpdateNetwork
中的每個刷新中重新應用。
客戶端可能定義了多個區域(例如,如果玩家正在操作遠端攝影機)。如果網路物件位於玩家的一個或多個AOI區域內,該玩家會感興趣,並從伺服器接收該NetworkObject
的伺服器更新。
NetworkTRSP需求
興趣區域系統使用NetworkTRSP
類別的位置值來確定物件的位置。對於任何參與AOI處理的網路物件,它必須在與NetworkObject
元件相同的遊戲物件上具有NetworkTRSP
衍生類別。
更多關於NetworkTRSP
的資訊在這裡。
這些Fusion的元件衍生自NetworkTRSP
,並且與AOI相容:
NetworkTransform
NetworkRigidbody3D
(Unity Physics附加元件)NetworkRigidbody2D
(Unity Physics附加元件)NetworkCharacterControllerPrototype
- 進階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()
可以在AOI之外使用,以強制玩家對物件感興趣,即使它們在其AOI範圍之外。
AreaOfInterestOverride
請參見NetworkTransform中的AreaOfInterestOverride。
可以在主NetworkTRSP
上設定AreaOfInterestOverride
,以指示伺服器應使用另一個網路物件的TRSP資料來確定玩家對NetworkObject
的興趣。
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);
}
全域
所有玩家都對這個NetworkObject
感興趣。這有效地停用了此網路物件的物件剔除,而且所有玩家都將收到此NetworkObject
的伺服器更新。
明確
任何玩家都不會對此網路物件感興趣,除非玩家的興趣被特別新增到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與物件興趣
物件興趣也會影響任何非靜態RPC的傳遞,因為這些RPC綁定到NetworkObject
的執行個體。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.");
}
}
}
行為興趣
伺服器模式(專用/主機/單人玩家)中的伺服器同儕節點可以將網路行為的所有已連網屬性(狀態)的複製限制為僅限到特定的玩家。
可以用自訂實作覆寫ReplicateTo(PlayerRef player)
方法,以便為不同的玩家選擇性地傳回真或偽。
注意: 這僅適用於伺服器模式和主機模式(非共享模式)。ReplicateTo()
僅在伺服器同儕節點有效,因為伺服器是伺服器模式下的唯一狀態授權。
注意: 物件興趣在行為興趣之前確定。如果一個網路物件不符合玩家的興趣,那麼該物件上的任何網路行為都不會被複製到該玩家。
注意: 行為興趣僅影響已連網屬性(具有[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;
}
}