Unityでシーンを移動した時のデータの引き継ぎ

今回はシーン移動時のデータの引き継ぎ方法を考えます。

通常であればシーン移動をする時にゲームオブジェクト等は引き継がれません。
変数の値を次のシーンでも使いたい時はstaticにしておけばシーン移動後もその値を使用する事が出来ます。

実際に試して確認してみます。

スポンサーリンク

シーン移動時にデータを引き渡せるかどうかの実験

まずはタイトル画面からゲーム画面にシーンが移動するとします。
タイトル画面のシーンにGameSystemというゲームオブジェクトを作成し、Add Componentで新しいスクリプトGameStartを設定します。

staticでgameData1というint型の変数を宣言し、50を入れておきます。

static1

上がサンプルタイトルでスタートボタンを押すとゲームシーンに移動します。

ゲームシーンに移動するとGameSystemオブジェクトは引き継がれません。
ゲームシーンに配置しているゲームオブジェクト(どれでもOK)にStaticDataというスクリプトを作成し取りつけます。

GameObject型のgameSystemを作成し、Start関数内でGameSystemを探します。
存在しないのでGameObject.Find(GameSystem);

だとエラーになります。

GameObject.Find(“GameSystem”);

だと読み出せます。
その後GameSystemに設定しているGameStartのgameData1を表示させようとしています。

static2

実際に実行するとちゃんと50がConsoleに出力されました。

次にstatic以外は引き継がれないのか確認してみます。
GameStartスクリプトに以下の変数を宣言します。

public var gameData2 : int = 30;
private var gameData3 : int = 10;

function GetGameData3() {
return gameData3;
}
gameData3はprivateなのでゲッターを準備しておきます。

次にゲームシーンに設置しているStaticDataスクリプトでそれらのデータを取得する処理を記述します。

記述が出来たのでタイトルシーンを開始し、スタートボタンを押してゲームシーンに移動してみてください。

static3

エラーが発生しました。
8行目でそんなものありませんよと言われています。
ということで、publicは使えない事がわかりました。

privateなデータも確認したいので、StaticDataのgameData2を出力している部分をコメントアウトします。
そして同じように実行してみます。

static4

今度は9行目でエラーが出ました。これはgameData3の値を取得している個所です。

これでstaticで宣言したデータの引き継ぎは出来るが、それ以外で宣言したデータは引き継がれない事がわかりました。
データの引き継ぎが出来る事はわかりましたが、ゲームオブジェクト自身が引き継がれていないのに、データだけ引き継がれているというちょっと不可思議な状態になってしまいます(スクリプトがクラスとして扱われてるからかな?)。

それに、主人公がシーンをまたいで存在したい、その他オブジェクトも次のシーンで使いたい場合もあると思います。
次のシーンは新しく主人公やその他オブジェクトを配置するという事も出来ますが、かなり面倒です。

そこでシーンをまたいでゲームオブジェクトを残す機能を追加します。

GameStartスクリプトに上のように記述します。
DontDestroyOnLoadは引数にゲームオブジェクトを指定すれば、そのゲームオブジェクトがシーンを移動する時に破棄されず、次のシーンにも登場するようになります。

static5

上がタイトルシーンに配置されているゲームオブジェクトです。

GameSystemにはGameStartスクリプトが設定され、ゲームオブジェクトを次のシーンでも使う処理が記述されています。
それではタイトルシーンのスタートボタンを押して、ゲームシーンに移動してみます。

static6

上がゲームシーンのヒエラルキーの一部です。ゲームシーンに移動してもGameSystemオブジェクトが残っています。

static7

StaticDataスクリプトで設定していたデバッグ出力は上のように出力されました。

これでシーン移動時のデータとゲームオブジェクトの引き渡しをする事が出来るようになりました。

シーンを移動した時に主人公等はステータス状態もあるのでそのまま引き継げるのは楽になりますね!
ただシーンをまたいでテストプレイする場合はいいんですが、そのシーンだけをテストする時は大変です・・・・(^_^;)

これはテスト用のゲームオブジェクトをつけておかないといけないんでしょうか・・・

シーンを移動した時に受け渡したいデータをクラスとして持って置き、
シーンそれぞれに残したいゲームオブジェクトとスクリプトの同じものを配置し、シングルトンパターン(同一インスタンスを生成しない)を使ってすでにスクリプトのクラスが存在していたらデータのクラスを生成しないようにするという風に作ればいいみたいです。

ここら辺はいずれ追記するかも?