Menu
CoddyTech

シングルトン

CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 13/60。

Inspector の参照先には、ドラッグして設定できるオブジェクトが必要です。ゲーム中にスポナーが作る敵はプレハブから生成されます。プレハブが参照できるのはアセットと自身のパーツだけで、シーン内のオブジェクトは参照できないため、敵の GameManager フィールドは空です。一般的な解決方法はシングルトンです。GameManager は、すべてのスクリプトがクラス名を通じてアクセスできるフィールドに、自分自身を格納します。

public class GameManager : MonoBehaviour
{
    public static GameManager Instance;
    private int kills;

    void Awake()
    {
        Instance = this;
    }

    public void EnemyDown()
    {
        kills++;
        Debug.Log("Kills: " + kills);
    }
}
// Enemy.cs、敵のプレハブに配置
public void Die()
{
    GameManager.Instance.EnemyDown();
    Destroy(gameObject);
}

static は、そのフィールドがオブジェクトではなくクラスに属することを意味します。GameManager オブジェクトごとに独自の kills が用意されますが、ゲーム全体で Instance は1つだけです。クラス名を使って GameManager.Instance のようにアクセスします。1分前に生成された敵も含め、どのスクリプトからでも、自身のフィールドに設定することなく読み取れます。

マネージャーは Awake で Instance = this; を設定します。ここで this はスクリプト自体を指します。Unity はどの Start よりも前にシーン内のすべての Awake を実行するため、ほかのスクリプトは Start から GameManager.Instance を使えます。シーン内に2つ目の GameManager があると、その自身で Instance を上書きしてしまいます。それを防ぐ方法は「シーンとレベル」の章で説明します。

challenge icon

チャレンジ

簡単

シングルトンを使って、流星がGameManagerにアクセスできるようにします。

  1. GameManager.csで、public static GameManager Instance;と、Instance = this;を含むAwake()を追加します。
  2. Meteor.csで、gameフィールドを削除し、代わりにGameManager.Instance.MeteorLanded()とGameManager.Instance.MeteorCaught()を呼び出します。

「プレイ」を押して流星を捕まえます。Consoleにエラーが表示されず、Caught: 1と表示されます。その後、「確認」を押します。

自分で試してみよう

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    public TMP_Text caughtText;
    public TMP_Text shieldText;
    private int caught;
    private int shield = 3;

    public void MeteorCaught()
    {
        caught++;
        caughtText.text = "Caught: " + caught;
    }

    public void MeteorLanded()
    {
        shield--;
        shieldText.text = "Shield: " + shield;
    }
}

本格的なゲームを作るのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド