Unityの変数をシーンを移動しても保持したい!
どうも、Linです。ペッパー、きかせてます。
Unityでゲームアプリを作成していると、たまに、
異なるシーン間で変数を共有したい
というシチュエーションが出てきませんか??
たとえば、シーンAで宣言した変数aを、シーンBでも使用したい場合ですね。

この場合の対処法をマスターしたので、忘れないうちに書き留めておこうと思います。
執筆にあたり、下記の神記事を参考にさせていただきました。
シーンを遷移しても、同じ数値をコンソール上に表示できるアプリを作ってみます。

シーンをAとBの2種類作成し、そこに空のゲームオブジェクトを置いてScriptA・ScriptBをそれぞれアタッチしてみてください。

Unityでシーン間で変数を共有する方法は次の2つ。
- publicなstaticな変数として宣言する方法
- ゲームオブジェクトを破壊せずに保持する方法
publicでstaticな変数として宣言する方法
まず、publicでstaticな変数として宣言する方法です。
Step1. publicでstaticな変数にする
シーン間で共有したい変数をpublicでstaticな変数として宣言します。
こうすることで、
ゲーム全体に変数が保存されることになるので、シーンが遷移してゲームオブジェクトが破棄されても変数が生き残るようになるのです。
今回のサンプルでは「a」という変数をシーンBで共有するので、この「a」をpublicでstaticな変数として宣言しましょう。
そして、今回はこのaに100を代入します。
ScriptAは、下記のコードのようになります。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScriptA : MonoBehaviour { public static int a=100; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
Step2. ゲッターとなる関数を作成
publicな変数を受け取るゲッター関数を作成します。
引き継ぎたい変数を、この関数の返り値として設定すればいいわけです。
今回は、ScriptBでgetA()というゲッターの関数を作ってみました。
public staic void getA(){ return a; }
シーン間で共有するためには、staticな関数として宣言して、ゲーム全体で保存されるようにする必要があります。
スクリプト「ScriptA」の全体としてはこんな感じになりますね。
返り値に変数aを設定してます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScriptA : MonoBehaviour { public static int a=100; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } public static int getA(){ return a; } }
Step3. ゲッターを呼び出す
ゲッター関数を異なるシーン上のスクリプトで呼び出しましょう。
呼び出し方は、
(変数を呼び出したい元のスクリプトのクラス名). ゲッター関数名
で大丈夫です。
今回の例では、ScriptBで「ScriptA」というスクリプトの「getA」というゲッターを呼び出したかったので、
ScriptA.getA();
とScriptBに記述すれば、publicでstaticな変数を引き継げるわけですね。
このシーンAから引き継いだ変数(ScriptA.getA())を変数bに代入して、printでコンソール上に表示します。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScriptB : MonoBehaviour { int b; // Use this for initialization void Start () { b = ScriptA.getA (); print (b); } // Update is called once per frame void Update () { } }
試しにシーンBでゲームを再生してみると、

コンソール上に「100」というシーンAから引き継いだaの値が表示されてますね。
書いていて混乱するほどわかりにくくなってきましたが、
publicでstaticな変数をゲッターで渡してやれば良い
ということです。シーンが遷移しても変数の中身が壊れることはありません。
シーン遷移してもゲームオブジェクトを破棄しないようにする方法
次は、DontDestroyOnLoad()というメソッドを使い、シーンを移動してもゲームオブジェクトを破棄しないようにする方法です。
Step1. publicでstaticな変数を宣言
シーン間で引き継ぎたい変数をpublicでstaticなもので宣言します。
今回の例では、
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScriptA : MonoBehaviour { public static int a=100; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
という感じにScriptAを編集。変数aをpublic、staticに宣言して100を代入します。
Step2. DontDestroyOnLoad()を使う
次に、DontDestroyOnLoadというメソッドをStart関数内で使います。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScriptA : MonoBehaviour { public static int a=100; // Use this for initialization void Start () { DontDestroyOnLoad (this); } // Update is called once per frame void Update () { } }
このメソッドは、
引数で指定したゲームオブジェクトをシーン遷移しても破棄されないようにする
もの。今回は引数で「this(スクリプトがアタッチされてるゲームオブジェクト)」を渡しているので、スクリプトがアタッチされた空のGameObjectは破棄されないわけですね。
Step3. 変数を取得する
最後に、遷移先のシーンから変数を取得します。
スクリプトのクラス名. 変数名
という形で記述すればオッケーです。
今回は、ScriptA からaという変数を取得したかったので、
ScritpA.a
でいいのですね。
シーンAから取得した変数をbというint型の変数に代入してやると、ScriptBは次のようになるはずです。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ScriptB : MonoBehaviour { int b; // Use this for initialization void Start () { int b = ScriptA.a; print (b); } // Update is called once per frame void Update () { } }
試しにシーンBでゲームを再生してみると・・・

コンソールに変数aの100が表示されますね。
Unityでシーン間で変数を共有したいときは変数をpublicでstaticなものへ
以上がUnityのシーン間で変数を共有する方法でした。
ポイントは、
- シーン間で共有したい変数をpublic・staticなものへ
- 遷移先のスクリプトで変数を受け取る
の2つしかありませんね。
今回、記事で紹介した、
- ゲッター関数を作る方法
- DontDestroyOnLoadメソッドを使う方法
のいずれかを試してみてください。
それでは!
Lin

おそらく、ブロガー。
今年でフリーランス 6年目。