2017-09-27 123 views
0

我是Unity的初学者。实现Unity Singleton的最佳方式是什么?

我目前在使用Singleton。

我在学习的时候有问题。

什么是最好的方式来实现统一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; 
     } 
    } 
} 

我们将不胜感激,如果你可以检查代码, 但我们也很感激几个关键点。

我已经看过几个文件,但他们只是变得复杂。 我的水平非常低。如果您能够轻松解释,我将不胜感激。

回答

2

这里是你的代码的一些言论: instance = go.AddComponent<T>(); 关于此行的关键是,AddComponent<>会导致脚本实例的创建和:

  1. 您有一行代码Instance属性里面的getter然后调用Awake()方法。所以你会通过这一行创建一个你的sript的实例,这与Awake()方法中写的内容无关。所以你可以摆脱Awake(),因为它什么也不做。唯一的情况是它会做一些有用的工作,当你尝试创建你的脚本的第一个实例(它只会将实例的值设置为第一个实例)。在其他情况下,它是无用的。所以如果你只用Instance属性创建你的单身人士 - 你不需要清醒。

  2. Awake本身是MonoBehaviour脚本的“有点构造函数”,但它的表现有所不同。关键是,在纯C#中,您可以在静态构造函数的帮助下轻松实现单例,但在MonoBehaviour中无法这样做。这意味着如果你已经有一个单例的实例,并且你将尝试创建你的单例实例,并且行T myNewInstance = new T();将会实际创建第二个实例。所以你的代码不会保护你免于直接创建实例。

  3. 此外,如果您使用gameObject.AddComponent<T>()方法,您的singletone代码不会阻止Unity创建新的脚本实例。

所以,没有100%的方法来创建一个团结MonoBehaviour singletone,但也有一些可能的解决方法。

例如,看看here。此解决方案与您的解决方案非常相似,但它也使用帮助器扩展方法public T GetOrAddComponent<T> (this Component child) where T: Component,您可以借用该解决方案。

另一种可能的解决方案是,您可以创建一个非MonoBehaviour派生的c# singleton class类似于用于获取MonoBehaviour类的包装,该类仅包含一个实例。但是你只能使用这个包装来管理这个MonoBehaviour类,否则你将能够根据你的需要创建尽可能多的MonoBehaviour实例。

1

有很多Singleton模式实现可用,但Unity环境与其他环境完全不同,所以实现与其他环境完全不同。

因此,在团结中,你应该做更多的事情,例如你应该为你的单身物件做一个预加载场景,并把它们作为场景中的组件。

但是你可以从Game Programming Patterns - Singleton学习的基础知识和基本原理和Wikipedia - Singleton Pattern

这里是统一Singleton模式的一些实现:

UnityGeek - Singleton

Unity Official Wiki - Singleton

而最好的实现是Unity Community - Singleton

相关问题