This document is about: FUSION 2
SWITCH TO

NetworkObjectProvider

INetworkObjectProvider

StartGame()のStartArgsで渡されたINetworkObjectProviderによって、Spawnedが呼ばれた際にアタッチされるゲームオブジェクトの取得/生成が行われます。

NetworkObjectProviderDefault

INetworkObjectProviderのデフォルト実装は、NetworkObjectProviderDefaultです。NetworkRunner開始時にStartArgsでObject Providerを指定しなかった場合、NetworkRunnerは、自身のゲームオブジェクトからINetworkObjectProviderコンポーネントを探します。もし実装が見つからない場合、NetworkRunnerは自動的にNetworkObjectProviderDefaultを追加します。

これは非常に基本的な実装で、Spawn()では(オブジェクトプールを使用せずに)プレハブをインスタンス化することでオブジェクトを生成し、Despawn()ではDestroy()によってオブジェクトを破棄します。

オブジェクトプーリング

オブジェクトを生成/破棄するかわりにプールするINetworkObjectProviderを作成する最も簡単な方法は、NetworkObjectProviderDefaultを継承して、InstantiatePrefabとDestroyPrefabInstanceをオーバライドすることです。

C#

public class PooledNetworkObjectProvider : NetworkObjectProviderDefault
{
    protected override NetworkObject InstantiatePrefab(NetworkRunner runner, NetworkObject prefab)
    {
        // Get object from pool and return it.
    }

    protected override void DestroyPrefabInstance(NetworkRunner runner, NetworkPrefabId prefabId, NetworkObject instance)
    {
        // Return the instance to the pool.
    }
}
ローカルステートのリセット

オブジェクトプールからオブジェクトを取得/返却する際は、オブジェクトのローカルステート(例:速度・アニメーション・パーティクル・タイマー・その他C#フィールドなど)を必ずリセットしてください。 そうしないと、そのステートが次の使用時に引き継がれてしまいます。 ネットワークステートは、手動でリセットする必要はありません。これらはFusionによって自動的にリセットされます。

独自オブジェクトのスポーン

プレハブを使用するかわりに、実行時に独自のネットワークオブジェクトを構築することが可能です。

重要: ネットワークオブジェクトをスポーン/アタッチした後は、NetworkBehaviourを追加/削除することはできません。ネットワークオブジェクトのNetworkBehaviourのカスタマイズは、スポーンする前にすべて完了している必要があります。ネットワークに関連しないコンポーネントなら、もちろんいつでも追加/削除することは可能です。

C#

public class BakingObjectProvider : NetworkObjectProviderDefault
{
  // For this sample, we are using very high flag values to indicate that we need to do a custom instantiate
  // Values lower than this will fall through the default instantiation handling.
  public const int CUSTOM_PREFAB_FLAG = 100000;

  // The NetworkObjectBaker class can be reused and is Runner independent.
  private static NetworkObjectBaker _baker;
  private static NetworkObjectBaker Baker => _baker ??= new NetworkObjectBaker();

  public override NetworkObjectAcquireResult AcquireInstance(NetworkRunner runner, in NetworkObjectAcquireContext context, out NetworkObject result) 
  {
    // Detect if this is a custom spawn by its high prefabID value we are passing.
    // The Spawn call will need to pass this value instead of a prefab.
    if (context.TypeId.IsPrefab && context.TypeId.AsPrefabId.RawValue == CUSTOM_PREFAB_FLAG) 
    {
      var go = GameObject.CreatePrimitive(PrimitiveType.Cube);
      var no = go.AddComponent<NetworkObject>();
      go.AddComponent<NetworkTransform>();
      go.name = $"Custom Object"; 
    
      // Baking is required for the NetworkObject to be valid for spawning.
      Baker.Bake(go);
    
      // Move the object to the applicable Runner Scene/PhysicsScene/DontDestroyOnLoad
      // These implementations exist in the INetworkSceneManager assigned to the runner.
      if (context.DontDestroyOnLoad) 
      {
        runner.MakeDontDestroyOnLoad(go);
      }  
      else 
      {
        runner.MoveToRunnerScene(go);
      }

      // We are finished. Return the NetworkObject and report success.
      result = no;
      return NetworkObjectAcquireResult.Success;        
    }
    
    // For all other spawns (regular prefabs AND scene objects, provided via context.AttachableInstance),
    // use the default behaviour.
    return base.AcquireInstance(runner, context, out result);
  }
}

Last updated on

Back to top