Menu
CoddyTech

Singleton عام

جزء من قسم هندسة الألعاب في Unity في رحلة Unity على Coddy. الدرس 43 من 64.

المفرد الأحادي في القسم 3 يتكوّن من خمسة أسطر يكرّرها كل مدير: خاصية Instance ثابتة، ودالة Awake تضبطها، والتحقق من وجود نسخة مكررة. تكتب فئة أساسية عامة هذه الأسطر مرة واحدة. ويرث منها كل مدير، مع تسمية نوعه باسمه:

public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    public static T Instance { get; private set; }

    protected virtual void Awake()
    {
        if (Instance != null && Instance != this)
        {
            Destroy(gameObject);
            return;
        }
        Instance = this as T;
    }
}

public class ScoreManager : Singleton<ScoreManager>
{
    public int score;
    public void Add(int points) { score += points; }
}

public class SoundManager : Singleton<SoundManager>
{
    public void Play(string clip) { Debug.Log("Playing " + clip); }
}
// في أي سكربت
ScoreManager.Instance.Add(10);
SoundManager.Instance.Play("coin");

ينتمي العضو الثابت في الفئة العامة إلى كل نوع يُنشأ منها: فـSingleton<ScoreManager> وSingleton<SoundManager> نوعان، لكل منهما Instance خاصة به، لذا لا يتشارك المديران واحدة. تكون ScoreManager.Instance من النوع ScoreManager أصلًا، وهذا هو الغرض من T. داخل الفئة الأساسية، لا يُعرف this إلا على أنه Singleton<T>، لذا يمرّره this as T على أنه المدير الذي يمثّله فعلًا.

الفئة الأساسية مجردة: لا يضع Unity على الكائنات سوى المديرين. إذا احتاج مدير إلى دالة Awake خاصة به، فيجب ألا يكتب void Awake() عادية. فهذا يحجب دالة الفئة الأساسية (ويحذّر المترجم من ذلك)، ولا يستدعي Unity إلا دالة المدير، ولا تُضبط Instance مطلقًا. استخدم override واستدعِ الفئة الأساسية أولًا:

protected override void Awake()
{
    base.Awake();
    score = 0;
}
challenge icon

التحدي

متوسط

امنح كلا المديرين أساسًا يبقى عند تحميل المشاهد.

  1. في PersistentSingleton، اكتب protected virtual void Awake(): يصبح الأول هو Instance ويبقى (DontDestroyOnLoad)؛ أما اللاحق فيدمّر نفسه.
  2. يرث كلٌّ من Wallet وMusicPlayer منه؛ احذف Instance الخاص بهما وAwake الخاص بـWallet.
  3. يتجاوز MusicPlayer الدالة Awake: يستدعي base.Awake()، ثم يسجّل Now playing: Adventure إذا كان هو Instance.

اضغط «العب»، وزُر الغابة ثم عُد: عملة واحدة. ثم اضغط «تحقق».

جرّب بنفسك

using UnityEngine;

public abstract class PersistentSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    public static T Instance { get; private set; }

    // Awake: احتفظ بأول نسخة عند تحميل المشاهد، ودمّر أي نسخة لاحقة
}

جميع دروس هندسة الألعاب في Unity

تدرّب بنفسك: Playground لـ Unity