Menu
CoddyTech
flag Ar iconالعربيةdown icon

Singleton عام

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

إن الـ singleton في القسم 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

التحدي

متوسط

بلدة وغابة، تربط بينهما بوابات أرجوانية. لكل مشهد كائن Wallet وكائن MusicPlayer خاصّان به، لذا يعمل كل منهما بمفرده، وتستدعي العملات Wallet.Instance.Add(1). اليوم، كل مدير هو Singleton من القسم 3، لذا تؤدي كل عملية تحميل إلى استبدال المحفظة بأخرى فارغة. امنح المديرين كليهما صنفًا أساسيًا عامًا يُبقيهما أثناء تحميل المشاهد:

  • في PersistentSingleton.cs، اكتب public abstract class PersistentSingleton<T>، وهو MonoBehaviour لأي نوع T من MonoBehaviour، مع Instance عام وثابت من النوع T لا يعيّنه سوى الصنف نفسه، وprotected virtual void Awake().
  • يحافظ Awake الخاص به على أول كائن من نوعه: يصبح ذلك الكائن Instance ويبقى أثناء تحميل المشاهد. أما أي كائن لاحق فيدمّر كائنه ولا يغيّر شيئًا.
  • يرث كل من Wallet وMusicPlayer منه، وتُحذف حقول Instance الخاصة بهما.
  • يحتفظ MusicPlayer بدالة Awake خاصة به تسجّل Now playing: Adventure. يجب أن تعمل بعد Awake الخاص بالصنف الأساسي، وللكائن الذي يبقى فقط، لكي تبدأ الموسيقى مرة واحدة في كل لعبة.

تُحرّك الأسهم اللاعب Player. اضغط Play، والتقط العملة، وانتقل إلى الغابة ثم عُد، وبعدها اضغط Check.

جرّب بنفسك

using UnityEngine;

// PersistentSingleton<T>: مثيل واحد يستمر عبر عمليات تحميل المشاهد
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

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