シングルトン
CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 13/56。
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分前に生成された敵も含め、どのスクリプトからでも、自身に設定するフィールドなしでこれを読み取れます。
マネージャーは、this がスクリプト自身を指す Awake で Instance = this; を設定します。Unity はどの Start よりも前にシーン内のすべての Awake を実行するため、他のスクリプトは Start から GameManager.Instance を使えます。シーン内に2つ目の GameManager があると、それ自身で Instance を上書きします。それを防ぐ方法は、Scenes and Levels の章で説明します。
チャレンジ
簡単隕石が降り注ぎます。Spawner はプレハブから Meteor を 1.5 秒ごとに落とし、矢印キーで Player を動かします。また、GameManager は MeteorCaught() でキャッチした数を、MeteorLanded() で地面に落ちた隕石の数を数えます。これらのスクリプトは準備できています。
Meteor スクリプトは game フィールドを通じて報告しますが、隕石はプレハブから生成されるため、game は空で、報告はすべて失敗します。シングルトンを使って修正しましょう。
GameManager.csで、型が GameManager の public static フィールドInstanceを追加し、Awake でこのスクリプトを代入します。Meteor.csで、gameフィールドを削除し、代わりにGameManager.Instanceを通じて報告します。
Play を押し、隕石をいくつかキャッチし、いくつか逃したら、Check を押します。
自分で試してみよう
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;
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。