2017-09-18 3 views
0

Es ist nur eine Frage, die mich auf Unity stört.Einheit Singleton Muster

Wir verwenden oft Singleton-Objekte wie Game-Manager und so und es gibt zwei Möglichkeiten, dies zu erreichen.

One ist eine Singleton.cs Cis-Klasse wie folgt zu verwenden:

using System; 
using System.Linq; 
using UnityEngine; 

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour 
{ 
    static T instance; 

    DateTime BirthTime; 

    public static T Instance 
    { 
     get 
     { 
      if (instance == null) 
       Initialize(); 

      return instance; 
     } 
    } 

    private void Awake() 
    { 
     BirthTime = DateTime.Now; 
    } 

    public static void Initialize() 
    { 
     if (instance == null) 
      instance = FindObjectOfType<T>(); 
    } 
} 

Und dann leiten unsere GameManager Als

GamaManager : Singleton<GameManager> 

In landläufigen Meinung, ist diese Methode CPU raubend, vor allem auf Mobile, da Unity die Hierarchie so vieler Objekte durchlaufen muss, um die in Singleton erwähnte Initialize-Methode zu verwenden.

Ein einfacher Ansatz ist privat Instanz zu erstellen und initialisieren es in Start- oder Awake als:

GameManager : MonoBehaviour 
{ 
    public static GameManager Instance { get; private set; } 

    void Start() 
    { 
     Instance = this; 
    } 
} 

Aber ich denke, es ist wie gleichen Code wieder zu schreiben und wieder. Kann jemand einen saubereren Ansatz vorschlagen?

+0

ich nur eine andere Art und Weise denken. Verwenden von 'GetComponent ()' anstelle von 'FindObjectOfType ()' – Jajan

Antwort

0

Was ist, wenn Ihre Game Manager-Klasse Ihre generische Singleton-Klasse erbt und die Suche nach GameObject mit diesem Typ vermeidet? Zum Beispiel:

public class Foo : Singleton<Foo> 

Ihre Foo-Klasse wird dann Zugriff auf „Instanz“ Eigenschaft, die Sie in Awake initialisieren.

+0

Dies ist genau, wie die zuvor genannte Klasse verwendet werden soll (das OP zeigt es sogar im Code), und auch nicht vollständig die Bedenken des OP zu adressieren. 'Initialize()' ist dazu gedacht, die Szene nach einer vorhandenen Instanz des Singleton zu durchsuchen, die auftreten kann, wenn Sie eine neue Szene nach dem Aufruf von 'DontDestroyOnLoad()' auf dem Singleton laden. In diesem Fall möchten Sie keinen neuen initialisieren - Sie möchten den Verweis auf den vorhandenen Verweis erhalten. Das OP fragt, ob es eine effizientere Möglichkeit gibt, das Objekt in der Szene zu finden. – Serlite

1

Ich bin nicht sicher, was Sie genau wollen, aber in Singletonmuster ich es vorziehen, eine Hauptklasse wie GameManager machen und es als Singleton-Klasse festgelegt, indem Sie dieses Stück Code verwendet:

static GameManager _instance; 
    public static GameManager instance { 
     get { 
      if (!_instance) { 
       _instance = FindObjectOfType<GameManager>(); 
      } 
      return _instance; 
     } 
    } 

Oder das Stück von Code, den Sie geschrieben haben, danach definieren Sie Variablen nach anderen Untermanagern Typ und Zugriff auf sie von GameManager Singleton.

Zum Beispiel:

public BulletManager myBulletManager; 

und es wie folgt verwendet werden:

GameManager.instance.myBulletManager.Fire();