今回は、戦闘シーンについて考える合間に、シーンを使ったサブシステム化を試します(シーンを使ってデバッグ用のドライバモジュールを追加します)。マネージャーシーン無しでもデバッグできるようにすることで、シーン毎の作業分担だけでなくシーンの結合(マージ作業)も容易になります。
前回の実装では、戦闘シーンはマネージャーシーンから呼び出すために最適化されていました。戦闘シーン単体で動かす場合は、マネージャーの代理になるドライバがあると便利です。
(前回の記事)
tomo-mana.hatenablog.com
ドライバの役目
ドライバはシーンを仮想化します。ドライバはマネージャーからは戦闘シーンに見え、戦闘シーンからはマネージャーシーンに見えます。ドライバはマネージャーの代わりにセーブデータの受け渡し、戦闘シーンのアクティブ化の切り替え、アクティベート時の敵生成指示を行います(デバッグ用)。
以下のように、段階的にシーン間のやりとりをドライバに置き換えていきます。
通常のシーケンス
前回のシーン構成(通常起動)は、マネージャーを使ってフィールドと戦闘を切り替えます。
(戦闘シーンをデバッグするために、フィールドを歩き回る必要があります)
ドライバ起動時のシーケンス
ドライバを追加した場合、通常起動のほかに、戦闘シーン単体で起動した場合は戦闘シーンだけを繰り返す、といったデバッグが可能になります。
ドライバシーンの追加
各プロセスの細かい手順は前回書いたので、今回は概要だけ書きます。
(1) Scene の作成、"BattleSceneDriver" にリネーム。
(2) File > BuildSettings に追加
(3) BattleSceneDriverシーン:Emptyゲームオブジェクトの作成(Service)
(4) Serviceゲームオブジェクト:スクリプト作成、追加
(5) Cameraゲームオブジェクトを無効化します。
追加された BattleSceneDriver は、Service だけを持ったシンプルな構造です。
(追加したコード)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.EventSystems; public class BattleSceneManagerService : MonoBehaviour { bool initialized = false; // Start is called before the first frame update void Start() { if( !SceneManager.GetSceneByName("BattleScene").isLoaded ){ SceneManager.LoadSceneAsync("BattleScene", LoadSceneMode.Additive); } } // Update is called once per frame void Update() { if( !initialized ){ if( SceneManager.GetSceneByName("BattleScene").isLoaded ){ Scene scene = SceneManager.GetSceneByName("BattleScene"); // フィールドシーンをアクティベート SceneManager.SetActiveScene(scene); // カメラON GameObject[] gameObjects = scene.GetRootGameObjects(); foreach( GameObject g in gameObjects ){ if( g.GetComponent<Camera>() != null ){ g.SetActive(true); break; } } // イベントシステムを有効化 foreach( GameObject g in gameObjects ){ if( g.GetComponent<EventSystem>() != null ){ g.SetActive(true); break; } } // キャンバスを有効化 foreach( GameObject g in gameObjects ){ if( g.GetComponent<Canvas>() != null ){ g.SetActive(true); break; } } initialized = true; } } } }
戦闘シーン(修正)
前回作成した戦闘シーン(BattleScene)を開き、以下を修正します。
(1) Emptyゲームオブジェクト追加(Initializer)
(2) Initializerオブジェクト:スクリプト作成、追加
戦闘シーンも、中身はこれからなので、今のところ Initializer のみです。
(追加したコード)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class BattleSceneInitializer : MonoBehaviour { // Start is called before the first frame update void Start() { /* マネージャーシーンが居ない(デバッグモード)の場合、 デバッグマネージャー(BattleSceneManager)を起動する */ if( !SceneManager.GetSceneByName("ManagerScene").isLoaded ){ if( !SceneManager.GetSceneByName("BattleSceneManager").isLoaded ){ SceneManager.LoadSceneAsync("BattleSceneManager", LoadSceneMode.Additive); } } } void Update() { } }
動作テスト
(1) 戦闘シーンを単体で起動します。ドライバシーンが起動されて、戦闘シーンがアクティベートされることが確認できました。
(2) マネージャーシーンから起動します。前回同様、フィールドと戦闘シーンが起動されて、フィールドがアクティベートされることが確認できました。
(3) 念のため、ドライバシーン単体での起動も確認します。戦闘シーンが起動されて、戦闘シーンがアクティベートされます。
(以下は、戦闘シーン単体で起動したときのHierarchyウィンドウ)
これで、戦闘シーン単体のデバッグができそうです。
次回
戦闘画面の構成
(以上)