Unityのスクリプトを書く際に、変数のスコープ(適用範囲)を理解することは非常に重要 です。
- ローカル変数・メンバー変数・グローバル変数の違い
- public・private・staticの使い分け
- スクリプト間での変数の共有方法(public、static)
- SerializeFieldの活用方法
- シングルトンとは何か?
適切に変数を管理することで、コードの可読性が向上し、バグを減らすことができます。
この記事でわかること
- ローカル変数・メンバー変数・グローバル変数の違いと使い方
- 変数のスコープ(適用範囲)を理解し、バグを減らす
- スクリプト間での変数の受け渡し方法(public、static)
- SerializeFieldを使った変数の管理とpublicとの違い
- シングルトンパターンを活用して、ゲーム全体のデータを統一的に管理する方法
変数のスコープ(適用範囲)・使い方
変数のスコープとは、その変数がどこでアクセスできるかを示す範囲のことです。スコープを適切に設定することで、コードの保守性が向上し、予期しないバグを防ぐことができます。
※ この他にも以下のサイトを参考にしてください。
スコープの種類
種類 | 適用範囲 | 用途 |
---|---|---|
ローカル変数 | メソッド内のみ | 一時的なデータ |
メンバー変数 | クラス内(private・public) | オブジェクトごとのデータ保持 |
グローバル変数 | staticを付けた変数 | ゲーム全体でのデータ共有 |
ローカル変数とメンバー変数(グローバル変数)の違い
ローカル変数とメンバー変数では使用できる範囲(スコープ)が異なります。
このスクリプトを試していただくとわかりますが、score1は数値が増えるがscore2は呼ばれるたびに初期化されるため増えないですね。
using UnityEngine;
public class ScopeExample : MonoBehaviour
{
public int score1; //メンバー変数
void Start()
{
score1 = 1;
}
void Update()
{
CountUp();
}
//voidの手前に何も書いてない場合は「public」になる
private void CountUp()
{
int score2 = 1; //ローカル変数
score1 += score1 +1;
score2 += score2 +1;
Debug.Log("score1:" + score1); //Consoleにデバッグ結果を出力する
Debug.Log("score2:" + score2); //Consoleにデバッグ結果を出力する
}
}
Unityで使われるpublicとprivateの違い
修飾子 | Inspectorで変更可能 | 他のスクリプトからアクセス可能 |
public | ✅ | ✅ |
SerializeField private | ✅ | ❌ |
private | ❌ | ❌ |
SerializeFieldを活用した変数管理
Unityでは、SerializeFieldを使うと、private変数でもInspectorから変更可能になります。
➡ SerializeFieldを使うとprivate変数でもInspectorで編集可能
➡ 外部スクリプトから直接変更できないため、安全性が向上
public class Player : MonoBehaviour
{
[SerializeField] private int health = 100; // Inspector で表示される
void Start()
{
Debug.Log("初期体力: " + health);
}
}
クラス間の変数の共有
public変数のクラス間の受け渡し
public class GameManager
{
public int highScore = 0; // すべてのスクリプトからアクセス可能
}
public class Player : MonoBehaviour
{
public GameManager gameManager; //Inspectorでアタッチが必要
void Start()
{
gameManager.highScore = 100;
Debug.Log("ハイスコア: " + gameManager.highScore);
}
}
static変数のクラス間の受け渡し
public class GameManager
{
public static int highScore = 0; // すべてのスクリプトからアクセス可能
}
public class Player : MonoBehaviour
{
void Start()
{
GameManager.highScore = 100;
Debug.Log("ハイスコア: " + GameManager.highScore);
}
}
シングルトンとは?
シングルトンとは、ゲーム全体で唯一のインスタンスを保証するデザインパターン です。通常、ゲームの進行状況や設定情報を管理するために使用されます。
シングルトンの実装例
➡ GameManager.Instanceでどこからでもアクセス可能
➡ シーンが変わっても DontDestroyOnLoad()でデータを保持
※ static変数を使用していたとしてもアタッチしたオブジェクトがシーン間でDestroyされたら変数の値は消えます。(誤情報が多いので誤解しないように!)
public class GameManager : MonoBehaviour
{
//static変数
public static GameManager Instance { get; private set; }
void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
}
シングルトンのメリットとデメリット
メリット | デメリット |
---|---|
データの一元管理が可能 | 依存関係が強くなりすぎると、テストが難しくなる |
グローバル変数より安全にデータ共有ができる | 乱用すると、設計が複雑になる可能性がある |
オブジェクトの重複を防ぐことで、メモリの無駄を減らせる |
まとめ
・ローカル変数 → メソッド内だけで使える、一時的なデータ保存に最適
・メンバー変数(public、private) → オブジェクトごとのデータ管理に最適
・グローバル変数(static) → すべてのスクリプトで共有可能、ただし制御が必要
・SerializeFieldを使うと、Inspectorで編集できるがスクリプト外部からは変更不可
・シングルトンを使えば、ゲーム全体のデータを安全に管理可能