【问题标题】:Best way to implement Unity Singleton?实现 Unity Singleton 的最佳方式?
【发布时间】:2018-03-08 21:50:21
【问题描述】:

我是 Unity 的初学者。

我目前正在实施单例。

我在学习时有问题。

像标题一样在 Unity 中实现 Singleton 的最佳方法是什么?

我明白为什么要使用单例。那是.. " 一次创建一个对象,并在需要时使用它。"

我理解正确吗?

有很多方法可以实现单例。这是正确的? 那么,众多方法中哪一部分是共同使用的呢?

我的单例代码是:

public class GameSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    protected static T instance = null;

    protected virtual void Awake()
    {
        Debug.Log ("instance was !!!!! >>" + instance);

        if(instance != null) // 최초 instance 유효성 검사
        {
            Debug.Log(">> Game Singleton already exist!");
            return;
        }

        instance = FindObjectOfType<T>(); // 
        Debug.Log("FindObj" + "/" + "instance is >> " + instance);
    }

    // Use this for initialization
    protected virtual void Start()
    {

    }

    // Update is called once per frame
    protected virtual void Update()
    {

    }

    protected virtual void OnDestroy()
    {
        if (instance != null)
        {
            instance = null;
        }
    } 

    public static T Instance
    {
        get
        {
            if(instance == null)
            {
                GameObject go = new GameObject();
                go.transform.position = Vector3.zero; // Vector3(0,0,0)
                go.transform.rotation = Quaternion.identity; // 회전 없음
                go.transform.localScale = Vector3.one;
                go.hideFlags = HideFlags.HideAndDontSave;
                instance = go.AddComponent<T>();
                instance.name = (typeof(T)).ToString();
                Debug.Log(">> Game Singleton instance create : " + instance);
            }
            return instance;
        }
    }
}

如果您能查看代码,我们将不胜感激, 但我们也很欣赏一些关键点。

我看过几个文件,但它们只会变得复杂。 我的水平很低。如果您能简单地解释一下,我将不胜感激。

【问题讨论】:

    标签: c# oop unity3d singleton


    【解决方案1】:

    以下是关于您的代码的一些说明:

    1. Instance 属性的getter 中,您有一行代码: instance = go.AddComponent&lt;T&gt;(); 关于这一行的要点是AddComponent&lt;&gt; 将导致创建脚本实例,然后调用Awake() 方法。因此,您将通过这一行创建您的 sript 实例,而 Awake() 方法中写入的内容无关紧要。所以你可以摆脱Awake(),因为它什么都不做。它会做一些有用的工作的唯一情况是当您尝试创建脚本的第一个实例时(它只会将实例的值设置为第一个实例)。在其他情况下,它是无用的。因此,如果您仅通过使用 Instance 属性来创建单例 - 您不需要清醒。

    2. Awake 本身是 MonoBehaviour 脚本的“某种构造函数”,但它的执行方式不同。关键是,在纯 c# 中,您可以借助 静态构造函数 轻松实现单例,但在 MonoBehaviour 中不能这样做。这意味着如果您已经有一个单例实例,并且您将尝试使用 T myNewInstance = new T(); 行创建您的单例实例,则实际上将创建第二个实例。因此,您的代码不会保护您免于直接创建实例。

    3. 另外,如果您使用gameObject.AddComponent&lt;T&gt;() 方法,您的单音代码不会阻止 Unity 创建新的脚本实例。

    因此,没有 100% 的方法可以在 Unity 中创建 MonoBehaviour 单音,但有一些可能的解决方法。

    例如,看看here。此解决方案与您的解决方案非常相似,但它也使用 public T GetOrAddComponent&lt;T&gt; (this Component child) where T: Component 辅助扩展方法,您可以将其借用到您的解决方案中。

    另一种可能的解决方案是,您可以创建一个非 MonoBehaviour 派生的c# singleton class,例如用于获取 MonoBehaviour 类的包装器,您希望该类只有一个实例。但是您必须只使用这个包装器来管理这个 MonoBehaviour 类,否则您将能够创建任意数量的 MonoBehaviour 实例。

    【讨论】:

      【解决方案2】:

      Singleton 模式的实现有很多,但是 Unity 环境和其他环境完全不同,所以实现也完全不同。

      所以在统一中你应该做更多的事情,例如你应该为你的单例对象制作一个预加载场景并将它们作为组件放置在场景中。

      但您可以从Game Programming Patterns - SingletonWikipedia - Singleton Pattern 学习基础知识和基础知识

      以下是 Unity 中单例模式的一些实现:

      UnityGeek - Singleton

      Unity Official Wiki - Singleton

      最好的实现是Unity Community - Singleton

      【讨论】:

      • 其实你并不需要一个带有单例组件的游戏对象,你可以在运行时创建一个游戏对象并在运行时添加一个具有单例模式的组件,只要只有一个:)
      • 是的,Unity社区-Singelton实现在场景中没有组件实例时已经这样做了,您可以查看源代码以获取更多信息:github.com/UnityCommunity/UnitySingleton/blob/master/Assets/…
      猜你喜欢
      • 2016-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 2021-12-23
      • 2014-03-10
      • 1970-01-01
      相关资源
      最近更新 更多