Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实现Unity Singleton的最佳方法?_C#_Oop_Unity3d_Singleton - Fatal编程技术网

C# 实现Unity Singleton的最佳方法?

C# 实现Unity Singleton的最佳方法?,c#,oop,unity3d,singleton,C#,Oop,Unity3d,Singleton,我是团结的初学者 我目前正在实现Singleton 我学习时有问题 在Unity中实现Singleton的最佳方法是什么 我明白为什么要用单身汉。那就是。。 一次创建一个对象并在需要时使用它 我理解得对吗 有很多方法可以实现单例。是吗? 那么,许多方法中的哪一部分是共同使用的呢 我的单例代码是: public class GameSingleton<T> : MonoBehaviour where T : MonoBehaviour { protected static T

我是团结的初学者

我目前正在实现Singleton

我学习时有问题

在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;
        }
    }
}
如果您能检查一下代码,我们将不胜感激, 但我们也希望了解一些关键点

我看过好几份文件,但都很复杂。
我的水平很低。如果您能简单地解释一下,我将不胜感激。

以下是关于您的代码的一些评论:

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

Awake本身是单行为脚本的一种构造函数,但它的性能不同。关键是,在纯c中,您可以借助静态构造函数轻松实现单例,但在MonoBehavior中,您不能这样做。这意味着,如果您已经有了一个单例实例,您将尝试使用行T myNewInstance=newt创建单例实例;第二个实例将实际创建。因此,您的代码不会保护您避免直接创建实例

另外,如果使用gameObject.AddComponent方法,单音代码不会阻止Unity创建新的脚本实例

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

例如,看一看。此解决方案与您的解决方案非常相似,但它也使用公共的T getOradComponent此组件子级where T:Component helper扩展方法,您可以将其借用到您的解决方案中


另一种可能的解决方案是,您可以创建一个非monobhavior类,该类派生自一个包装器,用于获取一个monobhavior类,您希望该类只有一个实例。但您只需使用此包装器来管理此MonoBehavior类,否则您将能够创建任意多的MonoBehavior实例。

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

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

Awake本身是单行为脚本的一种构造函数,但它的性能不同。关键是,在纯c中,您可以借助静态构造函数轻松实现单例,但在MonoBehavior中,您不能这样做。这意味着,如果您已经有了一个单例实例,您将尝试使用行T myNewInstance=newt创建单例实例;第二个实例将实际创建。因此,您的代码不会保护您避免直接创建实例

另外,如果使用gameObject.AddComponent方法,单音代码不会阻止Unity创建新的脚本实例

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

例如,看一看。此解决方案与您的解决方案非常相似,但它也使用公共的T getOradComponent此组件子级where T:Component helper扩展方法,您可以将其借用到您的解决方案中


另一种可能的解决方案是,您可以创建一个非monobhavior类,该类派生自一个包装器,用于获取一个monobhavior类,您希望该类只有一个实例。但是您只需要使用这个包装器来管理这个MonoBehavior类,否则您就可以创建任意多的MonoBehavior实例。

有很多单例模式实现可用,但是Unity环境完全不同 nt与其他环境不同,因此实现与其他环境完全不同

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

但你可以从和中学到基础知识和基本原理

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


最好的实现是

有很多单例模式实现可用,但Unity环境与其他环境完全不同,因此实现与其他环境完全不同

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

但你可以从和中学到基础知识和基本原理

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


最好的实现是

实际上你不需要有一个带有单例组件的游戏对象,你可以在运行时创建一个游戏对象,并在运行时添加一个带有单例模式的组件,只要只有一个:是的,这就是Unity Community-Singelton实现所做的,当场景中没有该组件的实例时,您可以查看源代码以了解更多信息:实际上,您不需要有带有singleton组件的游戏对象,您可以在运行时创建游戏对象,并在运行时使用单例模式向其添加组件,只要只有一个:是的,这就是Unity Community-Singelton实现已经在做的事情。当场景中没有组件实例时,您可以查看源代码以了解更多信息: