рдиреБрдХрд╕рд╛рди рдХреЗ рд╕рд╛рде рд╕рд┐рдВрдЧрд▓рдЯрди

рдкрд░рд┐рдЪрдп


рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреА рдПрдХ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдкреИрдЯрд░реНрди рдФрд░ рдПрдВрдЯреАрдкреИрдЯрд░реНрди рд╣реИрдВред рдЕрдХреНрд╕рд░ рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдореЗрдВ рдЕрдиреБрднрд╡ рдФрд░ рд╕реНрд╡рдпрдВ рдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреНрдЮрд╛рди рдХреЛ рдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЖрдкрдХреЗ рд╕рд╛рде рд╕рд┐рдВрдЧрд▓рдЯрди рдкреИрдЯрд░реНрди рдХреЗ рдЖрд╡реЗрджрди рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ , рдЕрд░реНрдерд╛рддреН рдиреЗрдЯ рдореЗрдВ рдЗрд╕рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХрддрд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ред


рдПрдХрд╛рдХреА рд╡рд╕реНрддреБ


рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдореИрдВ рдПрдХ рдЯреАрдо рдореЗрдВ рдХреЛрдб рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЯреАрдо рдХреЛ рдЙрддрд╛рд░рдиреЗ рдФрд░ рдпреВрдирд┐рдЯреА рдореЗрдВ рдХреБрдЫ рдкреИрдЯрд░реНрди рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдХреБрдЫ рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЗ рдЕрдВрджрд░ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рдХрд╛рдо рд▓реЗрддрд╛ рд╣реВрдВред


рдЗрд╕ рдкреНрд░рд╢реНрди 2 рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдиреЗрдЯ 1 рдкрд░ рд╕рд╛рд╣рд┐рддреНрдп рдХрд╛ рдЕрдзреНрдпрдпрди , рдФрд░ рдХрдИ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рдХрд╛рдо рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдирд┐рдореНрди рд╡рд░реНрдЧ рдХрд╛ рдЬрдиреНрдо рд╣реБрдЖ:


using UnityEngine;

/// <summary>
///    .
/// </summary>
/// <typeparam name="T">,    </typeparam>
/// <remarks>
///        OnDestroy  OnApplicationQuit
///      IsAlive.     
/// ,        .
/// 
/// 
///      Awake, OnDestroy, 
/// OnApplicationQuit    
/// base.Awake()  .
/// 
///    Initialization -      
///  .
/// 
///     unity,    
///   .    ,    
///       .
/// 
///  :
///     -  "CLR via C#"
///     - Chris Dickinson "Unity 2017 Game optimization"
///</remarks>

public class Singleton<T> : MonoBehaviour where T : Singleton<T>
{

    private static T instance = null;

    private bool alive = true;

    public static T Instance
    {
        get
        {
            if (instance != null)
            {
                return instance;
            }
            else
            {
                //Find T
                T[] managers = GameObject.FindObjectsOfType<T>();
                if (managers != null)
                {
                    if (managers.Length == 1)
                    {
                        instance = managers[0];
                        DontDestroyOnLoad(instance);
                        return instance;
                    }
                    else
                    {
                        if (managers.Length > 1)
                        {
                            Debug.LogError($"Have more that one {typeof(T).Name} in scene. " +
                                            "But this is Singleton! Check project.");
                            for (int i = 0; i < managers.Length; ++i)
                            {
                                T manager = managers[i];
                                Destroy(manager.gameObject);
                            }
                        }
                    }
                }
                //create 
                GameObject go = new GameObject(typeof(T).Name, typeof(T));
                instance = go.GetComponent<T>();
        instance.Initialization();
                DontDestroyOnLoad(instance.gameObject);
                return instance;
            }
        }

        //Can be initialized externally
        set
        {
            instance = value as T;
        }
    }

    /// <summary>
    /// Check flag if need work from OnDestroy or OnApplicationExit
    /// </summary>
    public static bool IsAlive
    {
        get
        {
            if (instance == null)
                return false;
            return instance.alive;
        }
    }

    protected void Awake()
    {
        if (instance == null)
        {
            DontDestroyOnLoad(gameObject);
            instance = this as T;
            Initialization();
        }
        else
        {
            Debug.LogError($"Have more that one {typeof(T).Name} in scene. " +
                            "But this is Singleton! Check project.");
            DestroyImmediate(this);
        }
    }

    protected void OnDestroy() { alive = false; }

    protected void OnApplicationQuit() { alive = false; }

    protected virtual void Initialization() { }
}

рдореИрдВ рдХрдИ рдкрд╣рд▓реБрдУрдВ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реВрдВрдЧрд╛ред


рд╡рд╕реНрддреБ рдирд┐рд░реНрдорд╛рдг


рдЬрдм рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдЯреАрдо> 3 рд▓реЛрдЧреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реБрдП, рдПрдХ рд╕реНрдерд┐рддрд┐ рдЕрдХреНрд╕рд░ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ рдЬрдм рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХрд╛ рдХреНрд░рдо рдЕрд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рд╕рдЦреНрддреА рд╕реЗ 3 рдмреЛрд▓рдирд╛ , рдЬрд╛рдЧрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХрд╛ рдХреНрд░рдо () рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╣реИ, рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдЪ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдкреНрд░рд▓реЗрдЦрди рдкрд╡рд┐рддреНрд░ рд╣реИ), рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЗрдВрд╕реНрдЯреЗрдВрд╕ {get;} рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдЗрд╕ рдХрд╖реНрдЯрдкреНрд░рдж рджреЛрд╖ рдХреЛ рдЦрддреНрдо рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ ред рдирддреАрдЬрддрди, рд╣рдо рдЕрдиреНрдп рд╡рд░реНрдЧреЛрдВ рдХреЗ рд╕рдЬрдЧ () рд╕реЗ рд╕рд┐рдВрдЧрд▓рдЯрди рддрдХ рдкреВрд░реА рдкрд╣реБрдВрдЪ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред


, Lazy, Awake() .

4-4, , Instance{get;}.



Unity тАФ Awake(). , , Initialization(). (KISS).



, DI SD. . .



, , OnDestroy(), OnApplicationQuit() 5:


Did you spawn new GameObjects from OnDestroy?

, , , . , IsAlive(), , . , ...



рддреЗрдЬреА рд╕реЗ, рдореИрдВ рдЗрд╕ рдирд┐рд╖реНрдХрд░реНрд╖ рдкрд░ рдкрд╣реБрдВрдЪрддрд╛ рд╣реВрдВ рдХрд┐ рдПрдХрддрд╛ рдкреНрд░рддрд┐рдорд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд┐рдВрдЧрд▓рдЯрди рдХреЗ рдмрд┐рдирд╛ рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдЕрдХреНрд╕рд░, рдЗрд╕ рдкреИрдЯрд░реНрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдЖрдкрдХрд╛ рдХреЛрдб рдЕрддреНрдпрдзрд┐рдХ рдЬреБрдбрд╝рд╛ рдФрд░ рдмреЗрд╣рдж рдирд╛рдЬреБрдХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред


рдзрдиреНрдпрд╡рд╛рджред


рд╕реВрддреНрд░реЛрдВ рдХрд╛ рдХрд╣рдирд╛ рд╣реИ


- рд░рд┐рдХреНрдЯрд░ рдЬреЗред "CR рдереНрд░реВ рд╕реА # #ред Microsoft.NET # рдлреНрд░реЗрдорд╡рд░реНрдХ 4.5 рдЗрди C #", 2013 рдкрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ


- https://www.codingame.com/playgrounds/1979/different-ways-to-implement-singleton-in--net-and-make-people-hate-you-along-the-way


- https://docs.unity3d.com/en/current/ScriptReference/MonoBehaviour.Awen.html


- https://ru.wikipedia.org/wiki/Design_Patterns


- рдбрд┐рдХрд┐рдВрд╕рди рдХреНрд░рд┐рд╕ "рдпреВрдирд┐рдЯреА 2017 рдЧреЗрдо рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди, рджреВрд╕рд░рд╛ рд╕рдВрд╕реНрдХрд░рдг", 2017


All Articles