36

Unityで、静的変数を持つグローバルクラスとしてどこからでもアクセスできるシングルトンゲームマネージャーを作成する良い方法は何ですか?それらの値をプルするすべてのクラスに同じ定数値を吐き出しますか?そして、Unityでそれを実装する方法は何でしょうか?GameObjectにアタッチする必要がありますか?視覚的にシーンに存在することなく、フォルダ内に存在することはできますか?

4

9 に答える 9

48

いつものように:場合によります。GameObjectにアタッチされたコンポーネントと から派生していないスタンドアロン クラスの両方の種類のシングルトンを使用しMonoBehaviourます。IMO全体的な問題は、インスタンスがシーン、ゲームオブジェクトなどのライフサイクルにどのようにバインドされているかです...そして、特に他のMonoBehaviourオブジェクトを参照するコンポーネントを持つ方が簡単で安全であることを忘れないでください。

  1. たとえば、呼び出されたときに永続化レイヤーから設定をロードする必要がある構成クラスなど、いくつかの値を提供するだけでよいクラスがあります。私はこれらのクラスを単純なシングルトンとして設計しています。
  2. 一方、一部のオブジェクトは、シーンがいつ開始されるかを知る必要があります。つまり、呼び出されるか、または他のメソッド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;
        }
    }
于 2012-12-05T19:55:55.410 に答える
0

これを行う 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;

于 2015-04-27T12:30:41.023 に答える