シングルトン
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 を上書きしてしまいます。それを防ぐ方法は「シーンとレベル」の章で説明します。
チャレンジ
簡単シングルトンを使って、流星がGameManagerにアクセスできるようにします。
GameManager.csで、public static GameManager Instance;と、Instance = this;を含むAwake()を追加します。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プレイグラウンド