一尘不染

Unity Singleton Manager类

c#

在Unity中,有什么好方法可以创建一个单例游戏管理器,它可以作为带有静态变量的全局类作为全局类在任何地方访问,该类将向每个提取那些常量的类吐出相同的常量值?在Unity中实现它的方式是什么?我是否必须将其附加到GameObject?可以只存在于文件夹中而没有视觉上出现在场景中吗?


阅读 416

收藏
2020-05-19

共1个答案

一尘不染

像往常一样:这取决于。我使用两种单例,即附加到组件的组件GameObject和不衍生自的独立类MonoBehaviour。IMO的总体问题是如何将实例绑定到场景,游戏对象的生命周期,……并且不要忘记,有时候拥有一个组件会更方便,尤其是引用其他MonoBehaviour对象更容易,更安全。

  1. 有些类只需要提供一些值,例如config类,该类需要在调用时从持久层加载设置。我将这些课程设计为简单的单例。
  2. 另一方面,某些对象需要知道何时启动场景,即Start调用场景或必须以Update其他方法执行动作。然后,我将它们实现为组件,并将它们附加到可以加载新场景的游戏对象上。

我设计了基于组件的单例(类型2),它分为两部分:GameObject名为的持久性(Main包含所有组件)和MainComponentManager用于管理它的平面单例(类型1)。一些演示代码:

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;
        }
    }
2020-05-19