2017-09-27 84 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

相關問題