Sceneの遷移をすると、遷移前のシーンは消えてしまいます(メモリからも破棄)。
しかし、Sceneを遷移しても、遷移前のシーンを残し、かつ、ゲームオブジェクトを残したままにしておきたいケースがあります。
なぜScene遷移を話をするかと言うと、メモリの制御(シーン破棄によりメモリから解放されるため)に役立つからです。
この記事では、遷移前のSceneを残しつつ、Sceneの遷移の方法を解説します。
遷移前のシーンを残したいケース
遷移前のシーンを残したいケースは以下のようなケースではないでしょうか?
・RPG
フィールドを歩いていて戦闘シーンに入り、戦闘が終わったらフィールドに戻る
・箱庭ゲーム
メインマップで遊んでいて、Shopなどの別の画面に遷移して、用事がなくなったらメイン画面に戻る。
・アクションゲーム
メインのゲームプレイ中、ポーズをかけてポーズ画面に切り替わる。ポーズ画面で用事が済んだらプレイ中のゲーム画面に戻る。
ユーザーが見たときの挙動の説明
(1)メインシーン
メインシーンを表示します。
(2)サブシーンに移動する
メインシーンからサブシーンに移動します。
実際の処理としては、メインシーンにサブシーンを追加して、メインシーンのゲームオブジェクトを非表示にしています。
(3)再び、メインシーンに戻る
サブシーンを破棄してメインシーンに戻ります。
内部処理的な話をすると、(2)で非表示にしたメインシーンのゲームオブジェクトを再び表示します。
≫ゲーム業界最強のマッチング力【シリコンスタジオエージェント】
実装方法の流れ
ここから実装の流れを解説します。
大まかな流れは、メインシーンにたいして、サブになるシーンを追加読み込みします。
ただし、サブシーンを読み込むだけだと、メインシーン重なるため、サブシーンが表示されている間はメインシーンの中のゲームオブジェクトを非表示にして対応します。
(1)メインシーンを読み込む
ゲーム起動時、メインシーンを読み込みます。
今回の例では、MainSceneシーンの「Controller」オブジェクトにメインシーンを制御するスクリプトMainScene.csを貼り付けています。
サブシーンを破棄したことを検出できるようにする(コールバックの設定)。
Start関数内で以下の処理を実行します。
SceneManager.sceneUnloaded += OnSceneUnloaded;
(2)サブシーンを表示する
以下の関数を呼び出してサブシーンを呼び出します。
//メインシーンにサブシーンを追加表示する
Application.LoadLevelAdditive("SubScene");
ただし、サブシーンを追加する前に、メインシーンからサブシーンが表示されている間に表示させたくないゲームオブジェトを非表示します。
メインシーンを制御しているMainScene.csの全体的なソースコードは以下の通りです。
MainScene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MainScene : MonoBehaviour {
public GameObject[] GameObjectsTohidden;
// Use this for initialization
void Start () {
//シーンが破棄されたときに呼び出されるようにする
SceneManager.sceneUnloaded += OnSceneUnloaded;
}
//サブボタンが押された
public void SubButton(){
//サブシーンを呼び出しているときに非表示にするゲームオブジェクト
foreach(GameObject obj in GameObjectsTohidden){
obj.SetActive(false);
}
//メインシーンにサブシーンを追加表示する
Application.LoadLevelAdditive("SubScene");
}
private void OnSceneUnloaded(Scene current)
{
//シーンが破棄されたときに呼び出される
//今回の例では、サブシーンが破棄されたら呼び出されるようになっています
Debug.Log("OnSceneUnloaded: " + current.name);
//本当は、どのシーンが破棄されたのか確認してから処理した方が良いかもしれない
//ゲームオブジェクトを表示する
foreach(GameObject obj in GameObjectsTohidden){
obj.SetActive(true);
}
}
}
(3)サブシーンを破棄してメインシーンに戻る
サブシーンからメイン画面に戻る方法を解説します。
以下の関数を呼び出してサブシーンを破棄します。
//サブシーンを破棄してメインシーンを表示する
SceneManager.UnloadScene("SubScene");
今回の例では、SubSceneシーンの「Controller」オブジェクトにサブシーンを制御するスクリプトSubScene.csを貼り付けています。具体的には、SubScene.cs内の処理でサブシーンを破棄しています。
全体的なソースコード
SubScene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class SubScene : MonoBehaviour {
//メイン画面に戻るボタン押されたときの処理
public void MainButton(){
//サブシーンを削除してメインシーンを表示する
SceneManager.UnloadScene("SubScene");
}
}
まとめ
いかがですか?
SceneManagerを使うなど工夫次第では、シーンを遷移しても、元に戻ったような挙動をさせることが可能です。