Unity单例管理器类

Dev*_*Art 33 c# singleton design-patterns unity-game-engine

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

Kay*_*Kay 45

总是如此:这取决于.我使用两种类型的单例,附加的组件GameObject和不是派生的独立类MonoBehaviour.IMO的整体问题是如何将实例绑定到场景,游戏对象的生命周期......并且不要忘记有时更方便的是让组件特别引用其他MonoBehaviour对象更容易和更安全.

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

我设计了基于组件的单例(类型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> ();
    }
Run Code Online (Sandbox Code Playgroud)

现在其他想要注册为Main组件的单身人士看起来像:

public class AudioManager : MonoBehaviour {
    private static AudioManager instance = null;
    public static AudioManager SharedInstance {
        get {
            if (instance == null) {
                instance = MainComponentManger.AddMainComponent<AudioManager> ();
            }
            return instance;
        }
    }
Run Code Online (Sandbox Code Playgroud)


Fat*_*tie 5

刚接触Unity的工程师通常不会注意到

您在ECS系统中不能有“单例”。

这是没有意义的。

您在Unity中只有XYZ位置的GameObjects。它们可以连接组件。

就像试图在.... Photoshop或Microsoft Word中使用“单例”或“继承”。

Photoshop文件-XY位置的像素
文本编辑器文件-X位置的字母
Unity文件-XYZ位置的GameObjects

就这么简单。

当然,在每个Unity项目中,您都绝对必须有一个预加载场景。

极其简单的操作方法:https : //stackoverflow.com/a/35891919/294884

这很简单,这不是问题。

一旦Unity包含一个“内置的预加载场景”(即,在创建一个预加载场景时一键保存),这将永远不再讨论。

(注A- 用于为Unity 编译组件的某些语言当然具有OO概念; Unity本身与OO没有任何联系。)

(注意B-在Unity的早期,您会尝试编写代码以“即时创建游戏对象-并使游戏对象保持唯一-并将其自身附加到该对象上。”除了怪异,从理论上讲FWIW并非如此可以确保唯一性(实际上甚至不在一个帧内)。再次,这完全是没有实际意义的,因为它是无关紧要的问题,在Unity中,一般行为只是在预加载场景中进行。)