This document is about: FUSION 2
SWITCH TO

スポーン(基礎)

はじめに

ネットワークオブジェクトは、通常のGameObject.Instantiate()でインスタンス化するかわりに、スポーンする必要があります。

実行時にネットワークオブジェクトをスポーンするには、Runner.Spawn()メソッドを使用します。シーンオブジェクトは、シーンがロードされた時に自動的にスポーンされるため、明示的にスポーンする必要はありません。

FusionはNetworkObjectにネットワーク間でユニークなIDを割り当てるため、すべてのクライアントはネットワークオブジェクトの各インスタンスを識別できて、それらの状態を正しく同期できるようになります。Runner.Spawn()メソッドによって、いつどのようにして新しいオブジェクトのインスタンスをネットワーク上の状態の集合に追加するかをFusionに伝えます。

重要!

ネットワークオブジェクトに対して、UnityのGameObject.Instantiate()メソッドを使用しないでください。ゲームオブジェクトはローカルでのみ生成されるため、Fusionのシミュレーションループからは完全に切り離され、ネットワーク上の状態を壊してしまいます。

Runner.Spawn

FusionのNetworkRunnerインスタンスのRunner.Spawn()メソッドは、UnityのGameObject.Instantiate()メソッドに似ています。メソッドに与えられるパラメーターは以下の通りです。

  1. NetworkObject型のプレハブ
  2. 位置(position)
  3. 回転(rotation)
  4. オブジェクトに対して入力権限を持たせたいクライアントのPlayerRef(ホストモードでのみ関係します)
  5. オブジェクトを複製する前に実行されるNetworkRunner.OnBeforeSpawned型のデリゲート

必須パラメーターはプレハブのみで、それ以外は任意のオプションです。

C#

var obj = Runner.Spawn(prefab, Vector3.zero, Quaternion.identity, Runner.LocalPlayer, MyOnBeforeSpawnDelegate);

Runner.Spawn()はどのクライアントからでも呼び出すことができますが、その結果はネットワークトポロジーによって異なります。

  • ホストモードでは、ホスト/サーバーのみがネットワークオブジェクトをスポーンできます。クライアント側でスポーンを実行したい場合、ホスト/サーバーにリクエストを(RPCなどで)送る必要があります。
  • 共有モードでは、すべてのクライアントがネットワークオブジェクトをスポーンできます。ネットワークオブジェクトをスポーンすると、状態権限は自動的にそのクライアントへ割り当てられます。

Input Authority

メソッドに特定のクライアントのPlayerRefを渡すと、そのクライアントに入力権限が割り当てられます。これは任意のオプションです。入力権限を持つクライアントは、オブジェクトに対して入力データを与えることができるようになり、(入力権限を持つクライアントと、ホスト/サーバーは)GetInput()からその入力構造体を取得できます。

オブジェクトが入力を必要としない、または入力権限を持つクライアントがいない場合は、nullを渡します。

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()は、NetworkRunnerNetworkObjectを紐づけた(NetworkRunner.Spawn()呼び出しの結果、またはNetworkObjectを含むシーンのロード)直後に呼び出されます。Spawned()コールバックは、FusionにおけるAwake()の代替とみなすことができ、「有効な」オブジェクトが「紐付けられた」後にのみ呼び出されます。

NetworkBehaviourISpawnedインターフェースを実装していて、Spawned()は空の仮想メソッドになっています。独自のNetworkBehaviourSpawned()を実装するには、単にSpawned()をオーバーライドしてください。

状態権限者がSpawned()で行うすべてのネットワークプロパティの更新は、他すべてのピア上でスポーンしたNetworkObjectインスタンスの初期値となります。しかしリモートのピアは、(関心領域、インタレストマネジメント、途中参加、優先順位などの理由で)常に状態権限者と同じティックにオブジェクトがスポーンするとは限りません。リモートのNetworkObjectが状態権限者より後のティックでスポーンした場合、そのティックに状態権限者が保持している値を初期値としてスポーンすることになります。

  • 状態権限を持つピアでのスポーンは、Runner.Spawn()直後にSpawned()が呼び出されます
  • 状態権限を持たないピアでは、NetworkRunnerがネットワーク上の状態を受信した際に、ローカルに存在しないNetworkObjectがスポーンします

NetworkRunnerに紐付けられるより前にNetworkObjectを初期化したい場合は、Runner.Spawn()から渡せるOnBeforeSpawnedコールバックを使用してください。

IAfterSpawned

IAfterSpawned.AfterSpawned()は、一連のNetworkObjectがスポーンして、すべてのISpawned.Spawned()コールバックが完了した後に呼び出されます。これは、FusionにおけるStart()の代替と考えることができます。スポーン後のNetworkBehaviourで、実行順序を気にせずに別のNetworkBehaviourの値を取得/設定する必要がある場合に、このコールバックを使用してください。

Despawn

ネットワークオブジェクトを削除するには、オブジェクトの状態権限を持つピアでRunner.Despawn()を呼び出してください。

Despawned

Runner.Spawn()によって、NetworkBehaviourのようなISpawnedを実装したクラスでSpawned()メソッドが呼び出されるのと同じように、Despawn()によって、IDespawnedを実装したクラスでDespawned()メソッドが呼び出されます。

Back to top