Unityで、静的変数を持つグローバルクラスとしてどこからでもアクセスできるシングルトンゲームマネージャーを作成する良い方法は何ですか?それらの値をプルするすべてのクラスに同じ定数値を吐き出しますか?そして、Unityでそれを実装する方法は何でしょうか?GameObjectにアタッチする必要がありますか?視覚的にシーンに存在することなく、フォルダ内に存在することはできますか?
9 に答える
いつものように:場合によります。GameObject
にアタッチされたコンポーネントと から派生していないスタンドアロン クラスの両方の種類のシングルトンを使用しMonoBehaviour
ます。IMO全体的な問題は、インスタンスがシーン、ゲームオブジェクトなどのライフサイクルにどのようにバインドされているかです...そして、特に他のMonoBehaviour
オブジェクトを参照するコンポーネントを持つ方が簡単で安全であることを忘れないでください。
- たとえば、呼び出されたときに永続化レイヤーから設定をロードする必要がある構成クラスなど、いくつかの値を提供するだけでよいクラスがあります。私はこれらのクラスを単純なシングルトンとして設計しています。
- 一方、一部のオブジェクトは、シーンがいつ開始されるかを知る必要があります。つまり、呼び出されるか、または他のメソッド
Start
でアクションを実行する必要があります。Update
次に、それらをコンポーネントとして実装し、新しいシーンをロードしても生き残るゲーム オブジェクトにアタッチします。
コンポーネント ベースのシングルトン (タイプ 2) を 2 つの部分で設計しました。すべてのコンポーネントを保持するGameObject
と呼ばれる永続的なものと、それを管理するためにMain
呼び出されるフラットなシングルトン (タイプ 1)です。MainComponentManager
いくつかのデモコード:
public class MainComponentManger {
private static MainComponentManger instance;
public static void CreateInstance () {
if (instance == null) {
instance = new MainComponentManger ();
GameObject go = GameObject.Find ("Main");
if (go == null) {
go = new GameObject ("Main");
instance.main = go;
// important: make game object persistent:
Object.DontDestroyOnLoad (go);
}
// trigger instantiation of other singletons
Component c = MenuManager.SharedInstance;
// ...
}
}
GameObject main;
public static MainComponentManger SharedInstance {
get {
if (instance == null) {
CreateInstance ();
}
return instance;
}
}
public static T AddMainComponent <T> () where T : UnityEngine.Component {
T t = SharedInstance.main.GetComponent<T> ();
if (t != null) {
return t;
}
return SharedInstance.main.AddComponent <T> ();
}
Main
コンポーネントとして登録したい他のシングルトンは次のようになります。
public class AudioManager : MonoBehaviour {
private static AudioManager instance = null;
public static AudioManager SharedInstance {
get {
if (instance == null) {
instance = MainComponentManger.AddMainComponent<AudioManager> ();
}
return instance;
}
}
これを行う 1 つの方法は、次のようにゲーム マネージャーを初期化するためだけにシーンを作成することです。
public class GameManager : MonoBehaviour {
static GameManager instance;
//other codes
void Awake() {
DontDestroyOnLoad(transform.gameObject);
instance = this;
}
//other codes
}
それだけです。あなたがする必要があるのはそれだけです。そして、ゲーム マネージャーを初期化した直後に、次のシーンをロードし、二度とこのシーンに戻らないようにします。
このチュートリアルをご覧ください: https://youtu.be/64uOVmQ5R1k?list=WL
編集:GameManager static instance;
に
変更static GameManager instance;