Spawning
概述
NetworkObjects
不能與常規GameObject.Instantiate一起具現化,而必須生成它們。
為了在運行階段生成NetworkObject
,請使用Runner.Spawn()
方法。場景物件不需要生成,它們在載入場景時會自動生成。
Fusion使用NetworkObject
來指派一個網路範圍內的唯一識別字,以便所有客戶端都能就哪個執行個體是哪個執行個體達成一致,並正確同步每個已連網物件的狀態。Runner.Spawn()
方法告訴Fusion何時以及如何將新物件執行個體新增到集體網路狀態。
重要事項!
請 不要 使用GameObject.Instantiate()
方法中的Unity的組建用於 已連網物件,這將只建立一個本機遊戲物件,該物件與Fusion模擬迴圈完全分離,且網路狀態中斷。
Runner.Spawn
Fusion NetworkRunner
執行個體上的Runner.Spawn()
方法模仿了Unity中的GameObject.Instantiate()
方法。可以提供給該方法的參數是:
NetworkObject
類型的預製件。- 一個位置
- 一個旋轉
PlayerRef
用於識別對物件具有輸入授權的客戶端。(僅適用於主機/伺服器模式)NetworkRunner.OnBeforeSpawned
類型的代表,在其他執行個體上複製物件之前運行
只有預製件是必填參數,所有其他參數都是可選的。
C#
var obj = Runner.Spawn(prefab, Vector3.zero, Quaternion.identity, Runner.LocalPlayer, MyOnBeforeSpawnDelegate);
儘管任何客户端都可以調用Runner.Spawn()
,結果將因網路拓撲而不同。
- 在主機和伺服器模式下,只有主機/伺服器可以生成
NetworkObjects
。取而代之地,客戶端需要向主機/伺服器發送請求(如RPC)以請求生成。 - 在共享模式下,任何客戶端都可以生成
NetworkObject
。生成NetworkObject
會自動將狀態授權分配給客戶端。
輸入授權
透過將輸入授權的PlayerRef
傳遞給方法,將輸入授權指派給特定的客戶端;這是可選的。被授予輸入授權的客戶端將能夠為物件提供輸入資料,並且(除了主機或伺服器之外)允許在GetInput()
中査詢該輸入結構。
如果物件不需要輸入或沒有客戶端對其具有輸入授權,則可以取而代之傳遞null
。
OnBeforeSpawned
NetworkRunner.OnBeforeSpawned
參數可以採用與委託簽名匹配的方法或lambda運算式。
C#
public delegate void OnBeforeSpawned(NetworkRunner runner, NetworkObject obj);
此委託在建立物件後但在所有執行個體上同步之前被叫用。這允許調用者在系統的任何其他部分能夠存取物件之前對其執行額外的自訂初始化。這是初始化自訂網路屬性的好地方。
C#
private void MySpawnFunction(){
Runner.Spawn(
_objPrefab,
Vector3.zero,
Quaternion.identity,
inputAuthority: null,
InitializeObjBeforeSpawn,
predictionKey: null
);
}
private void InitializeObjBeforeSpawn(NetworkRunner runner, NetworkObject obj)
{
var objSB = obj.GetComponent<ObjSimulationBehaviour>();
objSB.InitializeObjSettings(_currentExplosionForce);
}
也可以使用lambda運算式傳遞更多參數。
C#
private void MySpawnFunction(){
Runner.Spawn(
_objPrefab,
Vector3.zero,
Quaternion.identity,
inputAuthority: null,
(Runner, NO) => NO.GetComponent<MyCustomBehaviour>().Init(myInt, myParameter)
predictionKey: null
);
}
已生成
在NetworkRunner
附加NetworkObject
後立即調用ISpawned.Spawned()
(要麼是NetworkRunner.Spawn()
調用的結果,要麼是載入了包含NetworkObject
的場景)。Spawned()
回調可以被認為是Fusion對Awake()
的替代,在物件被附加並且有效後被調用。
NetworkBehaviour
使用空的虛擬Spawned()
方法執行了ISpawned
介面。要為自訂的NetworkBehaviour
執行Spawned()
,只需覆寫Spawned()
即可。
在Spawned()
中對狀態授權所做的任何已連網屬性值更改,都將是所有其他同儕節點上該NetworkObject
的所有已生成執行個體的初始值。但是,遠端同儕節點可能並不總是與狀態授權在同一刷新生成物件(由於興趣區域、興趣管理、延遲加入和優先順序)。當NetworkObject
在比狀態授權晚的某個刷新遠端生成時,它將以狀態授權在該晚的刷新的值來生成。
- 對於狀態授權的同儕節點上的生成,會在
Runner.Spawn()
之後立即調用Spawned()
。 - 對於非狀態授權的同儕節點,當
NetworkRunner
接收到不在本機上存在的NetworkObject
的網路狀態時,會生成NetworkObject
。
如果NetworkObject
應在附加到NetworkRunner
之前初始化,請使用提供給Runner.Spawn()
的預先生成OnBeforeSpawned回調。
IAfterSpawned
在一批NetworkObject
已生成並完成全部ISpawned.Spawned()
回調之後調用IAfterSpawned.AfterSpawned()
。這可以被認為是Fusion對Start()
的替代方案。當NetworkBehaviour
在生成後需要在另一個NetworkBehaviour
中獲取或設定值時,使用此回檔,而不考慮執行順序。
取消生成
要移除網路物件,對該物件具有狀態授權的同儕節點可以調用Runner.Despawn()
。
已取消生成
類似於Runner.Spawn()
觸發執行ISpawned
的類別的Spawned()
方法調用,如NetworkBehaviour
,Despawn()
將導致針對執行IDespawned
的類別調用Despawned()
方法。