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()方法。