スポーン(基礎)
はじめに
ネットワークオブジェクトは、通常のGameObject.Instantiate()
でインスタンス化するかわりに、スポーンする必要があります。
実行時にネットワークオブジェクトをスポーンするには、Runner.Spawn()
メソッドを使用します。シーンオブジェクトは、シーンがロードされた時に自動的にスポーンされるため、明示的にスポーンする必要はありません。
FusionはNetworkObject
にネットワーク間でユニークなIDを割り当てるため、すべてのクライアントはネットワークオブジェクトの各インスタンスを識別できて、それらの状態を正しく同期できるようになります。Runner.Spawn()
メソッドによって、いつどのようにして新しいオブジェクトのインスタンスをネットワーク上の状態の集合に追加するかをFusionに伝えます。
重要!
ネットワークオブジェクトに対して、UnityのGameObject.Instantiate()
メソッドを使用しないでください。ゲームオブジェクトはローカルでのみ生成されるため、Fusionのシミュレーションループからは完全に切り離され、ネットワーク上の状態を壊してしまいます。
Runner.Spawn
FusionのNetworkRunner
インスタンスのRunner.Spawn()
メソッドは、UnityのGameObject.Instantiate()
メソッドに似ています。メソッドに与えられるパラメーターは以下の通りです。
NetworkObject
型のプレハブ- 位置(position)
- 回転(rotation)
- オブジェクトに対して入力権限を持たせたいクライアントの
PlayerRef
(共有モードでは使用しません) - オブジェクトを複製する前に実行される
NetworkRunner.OnBeforeSpawned
型のデリゲート
必須パラメーターはプレハブのみで、それ以外は任意のオプションです。
備考: Spawn
メソッドで渡した位置と回転は、メソッドを実行したピアのオブジェクトのtransform
にのみ影響します。この位置と回転を他のピアに反映させるには、NetworkTransform
・NetworkTRSP
を継承したコンポーネント・transform
を同期する完全に独自のコンポーネントのいずれかが必要です。
C#
var obj = Runner.Spawn(prefab, Vector3.zero, Quaternion.identity, Runner.LocalPlayer, MyOnBeforeSpawnDelegate);
どのクライアントもネットワークオブジェクトをスポーンできます。ネットワークオブジェクトの状態権限は、スポーンしたクライアントに割り当てられます。
{% if Fusion_v2 %}
OnBeforeSpawned
NetworkRunner.OnBeforeSpawned
パラメーターには、シグネチャが一致するメソッドかラムダ式を渡すことができます。
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);
}
多くのパラメーターを渡すことができるラムダ式を使用することも可能です。
C#
private void MySpawnFunction(){
Runner.Spawn(
_objPrefab,
Vector3.zero,
Quaternion.identity,
inputAuthority: null,
(Runner, NO) => NO.GetComponent<MyCustomBehaviour>().Init(myInt, myParameter)
predictionKey: null
);
}
Spawned
ISpawned.Spawned()
は、NetworkRunner
がNetworkObject
を紐づけた(NetworkRunner.Spawn()
呼び出しの結果、またはNetworkObject
を含むシーンのロード)直後に呼び出されます。Spawned()
コールバックは、FusionにおけるAwake()
の代替とみなすことができ、「有効な」オブジェクトが「紐付けられた」後にのみ呼び出されます。
NetworkBehaviour
はISpawned
インターフェースを実装していて、Spawned()
は空の仮想メソッドになっています。独自のNetworkBehaviour
でSpawned()
を実装するには、単にSpawned()
をオーバーライドしてください。
C#
public class Example : NetworkBehaviour
{
public override void Spawned()
{
// Use this instead of Start / Awake for NetworkObjects
}
}
状態権限者がSpawned()
で行うすべてのネットワークプロパティの更新は、他すべてのピア上でスポーンしたNetworkObject
インスタンスの初期値となります。しかしリモートのピアは、(関心領域、インタレストマネジメント、途中参加、優先順位などの理由で)常に状態権限者と同じティックにオブジェクトがスポーンするとは限りません。リモートのNetworkObject
が状態権限者より後のティックでスポーンした場合、そのティックに状態権限者が保持している値を初期値としてスポーンすることになります。
- 状態権限を持つピアでのスポーンは、
Runner.Spawn()
直後にSpawned()
が呼び出されます - 状態権限を持たないピアでは、
NetworkRunner
がネットワーク上の状態を受信した際に、ローカルに存在しないNetworkObject
がスポーンします
Despawn
ネットワークオブジェクトを削除するには、オブジェクトの状態権限を持つピアでRunner.Despawn()
を呼び出してください。
Despawned
Runner.Spawn()
によって、NetworkBehaviour
のようなISpawned
を実装したクラスでSpawned()
メソッドが呼び出されるのと同じように、Despawn()
によって、IDespawned
を実装したクラスでDespawned()
メソッドが呼び出されます。
C#
public class Example : NetworkBehaviour
{
public override void Despawned()
{
// Use this instead of Destroy for NetworkObjects
}
}
Back to top