Vzor singleton v Unity

Unity Development

5 years ago

Návrhový vzor singleton je užitečný při psaní komponent v Unity jako je game manager nebo localization manager. Rád bych se s vámi podělil o implementaci, kterou nyní používám ve svém projektu.

Inspirace

Při návrhu své implementace jsem se inspiroval několika zdroji:

  • Localization Manager sample - přístup používající metodu Awake() , která po vytvoření první instance všechny nové zničí.
  • Unity Community Wiki - tato implementace zaručeně vytvoří pouze jednu instanci a je thread-safe díky zámkům.
  • Singleton pattern od Jona Skeeta - již poněkolikáté jsem zavítal na tento excelentní blog post o implementaci singletonu v C#, vřele doporučuji přečíst!

Kód

Poznámka: Tento kód vyžaduje kvůli typu Lazy<T> povolení .NET 4 scripting runtime.

  1. Otevřte nastavení Edit > Project Settings > Player.
  2. V záložce Configuration klikněte na drop-down Scripting Runtime Version a vyberte .NET 4.x Equivalent. Pro použití změn bude nutné restartovat Unity.

Vysvětlení

Má verze singletonu je implementovaná jako generická třída která dědí od MonoBehaviour. To je nutné pro přístup k metodě DontDestroyOnLoad kterou využíváme v CreateSingleton. Typový argument také dědí od MonoBehaviour abychom dostávali všechny zprávy jako je Awake, Start a Update. Při použití ve zděděné tříde předáváme ji samotnou jako typový argument. To se může zdát "zacyklené" ale jednoduše tím říkáme "třída X je singleton typu X". Pro vzor samotný jsem zvolil verzi s použitím Lazy<T> kterou doporučuje Jon Skeet ve svém článku. Lazy<T> se za nás postará o thread-safety a tak se vyhneme nutnosti používat v kódu zámky. Inicializace instance singletonu je přímočará - vytvoříme si nový prázdný GameObject, připojíme k němu naši komponentu a označíme jej tak, aby nebyl při načtení nové scény odstraněn.