This document is about: FUSION 2
SWITCH TO

Scene Loading

概要

FusionにはUnityのシーンを処理する実装は含まれていませんが、INetworkSceneManagerインターフェースによって、様々なシーン関連のイベント(シーン遷移など)にどのように反応するかを定義できます。INetworkSceneManagerの実装は、NetworkRunnerに渡した後にSceneManagerとみなされます。

INetworkSceneManagerの実装は、NetworkRunner.StartGame()StartGameArgs.SceneManagerで渡す必要があります。実装が渡されない(null)なら、FusionはNetworkSceneManagerDummyクラスのインスタンスを作成し、シーンオブジェクトを生成できない旨のエラーログを出力します。

Fusionにはデフォルト実装のNetworkSceneManagerDefaultが用意されていて、以下のことが可能です。

  • シーンのロード・アンロード
  • Addressableなシーンのロードに対応
  • アクティブなシーンのリロード
  • 最大8つ同時でAdditiveなシーンのロード
  • マルチピアモードに対応(各NetworkRunnerに対しての、正しいPhysicsSceneの関連付け)

シーンのロード・アンロード

重要: LoadScene()UnloadScene()は、サーバー/ホストまたはマスタークライアントからのみ呼び出すことができます。(これはNetworkSceneManagerDefaultによって強制されていて、独自実装でも同様に強制する必要があります)

シーンをロードするには、SceneRefLoadSceneParametersを渡してNetworkRunner.LoadScene()を呼び出します。LoadSceneMode.Singleでは前のシーンは全てアンロードされますが、LoadSceneMode.Additiveでは前のシーンはロードされたままになります。

C#

// Loading 3 scenes in additive mode.
if (Runner.IsSceneAuthority) {
  Runner.LoadScene(SceneRef.FromIndex(1), LoadSceneMode.Additive);
  Runner.LoadScene(SceneRef.FromIndex(2), LoadSceneMode.Additive);
  Runner.LoadScene(SceneRef.FromIndex(3), LoadSceneMode.Additive);
}

SceneRefのインデックスは、Unityのシーンのビルドインデックスです。現在のシーンのインデックスを取得するには、SceneManager.GetActiveScene().buildIndexを使用します。他のシーンのインデックスは、SceneUtility.GetBuildIndexByScenePathで見つけることができます。例えば、Assets/Scenes/GameScene.unityに格納されているシーンのロードは、以下のようなコードになります。

C#

  Runner.LoadScene(SceneRef.FromIndex(SceneUtility.GetBuildIndexByScenePath("Assets/Scenes/GameScene.unity")), LoadSceneMode.Additive);

シーンをアンロードするには、アンロードするシーンのSceneRefを渡して、NetworkRunner.UnloadScene()を呼び出します。

C#

// Unloading scene 1.
if (Runner.IsSceneAuthority) {
  Runner.UnloadScene(SceneRef.FromIndex(1));
}

シーンのアンロードとロードを順番に行って、シーンを再ロードすることも可能です。NetworkSceneManagerDefaultVersionフィールドはカウンタとして動作し、シーンをロード・アンロードするたびに増加します。この値は、シーンオブジェクトのIDの登録に使用され、たとえ同じシーンを再ロードしたとしても、前のシーンと新しいシーンは差別化されます。

C#

// Reloading scene 2.
if (Runner.IsSceneAuthority) {
  Runner.UnloadScene(SceneRef.FromIndex(2));
  Runner.LoadScene(SceneRef.FromIndex(2), LoadSceneMode.Additive);
}

SceneRefは、シーンのインデックスからSceneRef.FromIndex(int index)で作成するか、主にAddressableなシーンのパスからSceneRef.FromPath(string path)で作成します。

独自のNetwork Managerの作成

INetworkSceneInfo

ユーザーが操作するアクティブなシーン情報を表します。このインターフェースはアンマネージド型で実装し、シーンローディングを適切に同期するためにNetworkRunnerで通信されます。シーン権限者(ホスト/サーバーまたはマスタークライアント)がシーン情報を変更すると、NetworkRunnerに登録されているINetworkSceneManagerOnSceneInfoChanged()が呼ばれます。

NetworkSceneInfoDefault

INetworkSceneInfoのデフォルト実装で、最大8つのアクティブなシーンに対応します。独自実装を作成するための良い参考になるでしょう。

INetworkSceneManager

INetworkSceneManagerの独自実装をStartGameArgsに渡すと、シーンローディングをどのように処理するかを完全に制御できます。独自実装で、Runner.InvokeSceneLoadStart(sceneRef)Runner.InvokeSceneLoadDone(SceneLoadDoneArgs)を呼ぶ必要があることに注意しましょう。デフォルトの挙動はNetworkSceneManagerDefaultの実装を確認してください。

独自のSceneManagerを実装する場合、インターフェースで以下を実装してください。

  • void Initialize(NetworkRunner runner)NetworkRunnerが初期化された時に呼ばれます。NetworkRunnerの参照を格納したり、必要な事前処理が行うために使用してください。

  • void Shutdown()NetworkRunnerが停止した時に呼ばれます。参照を開放したり、保留中の処理を停止するために使用してください。

  • bool IsBusySceneManagerがシーンのロード等でビジー状態であることを、NetworkRunnerや他のシステムに知らせる必要がある場合に使用してください。

  • Scene MainRunnerScene:どのシーンがNetworkRunnerのメインのシーンであるかを知るために使用してください。これは主にマルチピアモードで使用されます。(詳細はデフォルト実装を確認してください)

  • bool TryGetPhysicsScene2D(out PhysicsScene2D scene2D):2D物理シーンをoutパラメーターに出力し、実行結果を返します。

  • bool TryGetPhysicsScene3D(out PhysicsScene scene3D):3D物理シーンをoutパラメーターに出力し、実行結果を返します。

  • void MakeDontDestroyOnLoad(GameObject obj):ロード時にオブジェクトが破棄されないようにします。マルチピアモードで使用されます。(詳細はデフォルト実装を確認してください)

  • void MoveToRunnerScene(GameObject obj):オブジェクトをNetworkRunnerのシーンに移動します。マルチピアモードでのみ使用されます。(詳細はデフォルト実装を確認してください)

  • bool IsRunnerScene(Scene scene):シーンがNetworkRunnerのシーンかどうかを返します。マルチピアモードで使用されます。(詳細はデフォルト実装を確認してください)

  • NetworkSceneAsyncOp LoadScene(SceneRef sceneRef, LoadSceneParameters parameters):新しいシーンをロードするために使用してください。シーンのロード方法は完全に開発者次第ですが、NetworkRunner.RegisterSceneObjects(SceneRef scene, NetworkObject[] objects, byte loadId = 0)で新しくロードしたNetworkObjectを登録するステップが必要です。追加のloadIdパラメーターを渡すことで、各シーンがシーンオブジェクトのユニークIDを生成することが保証されます。

  • NetworkSceneAsyncOp UnloadScene(SceneRef sceneRef):シーンをアンロードするために使用してください。

  • void OnSceneInfoChanged()NetworkRunnerINetworkSceneInfoが変更された時に呼ばれます。クライアントでシーンローディングの反応・実行するために使用してください。

  • SceneRef GetSceneRef(string sceneName):与えたシーン名のSceneRefを返すために使用してください。

Back to top