النمط Singleton
جزء من قسم بناء ألعاب حقيقية في رحلة Unity على Coddy. الدرس 13 من 56.
يحتاج مرجع Inspector إلى شيء لإسقاطه عليه. تأتي الأعداء التي ينشئها مولّد أثناء اللعبة من prefab، ولا يمكن لـ prefab الإشارة إلا إلى الأصول وأجزائه الخاصة، وليس إلى كائن في مشهد، لذا يكون حقل GameManager لديها فارغًا. الحل المعتاد هو singleton: يخزّن GameManager نفسه في حقل يمكن لكل برنامج نصي الوصول إليه عبر اسم الفئة.
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
private int kills;
void Awake()
{
Instance = this;
}
public void EnemyDown()
{
kills++;
Debug.Log("Kills: " + kills);
}
}// Enemy.cs، على قالب العدو الجاهز
public void Die()
{
GameManager.Instance.EnemyDown();
Destroy(gameObject);
}تعني static أن الحقل يتبع الفئة، لا كائنًا. سيحصل كل كائن GameManager على kills خاص به، لكن لا يوجد سوى Instance واحد في اللعبة كلها، ويمكنك الوصول إليه باستخدام اسم الفئة: GameManager.Instance. يمكن لأي برنامج نصي قراءته، بما في ذلك عدو تم إنشاؤه قبل دقيقة، من دون الحاجة إلى ملء حقل خاص به.
يعيّن المدير Instance = this; في Awake، حيث يشير this إلى البرنامج النصي نفسه. تشغّل Unity كل دوال Awake في المشهد قبل أي دالة Start، لذا يمكن للبرامج النصية الأخرى استخدام GameManager.Instance بدءًا من دالة Start الخاصة بها. سيستبدل GameManager ثانٍ في المشهد قيمة Instance بنفسه؛ يوضّح فصل Scenes and Levels كيفية منع ذلك.
التحدي
سهلتتساقط النيازك. يُسقط Spawner عنصر Meteor من قالب أولي كل 1.5 ثانية، وتحرك الأسهم اللاعب، ويحصي GameManager حالات التقاط النيازك باستخدام MeteorCaught() وحالات ارتطام النيازك بالأرض باستخدام MeteorLanded(). هذه البرامج النصية جاهزة.
يُبلّغ البرنامج النصي Meteor عبر الحقل game، لكن النيازك تأتي من قالب أولي، لذا يكون game فارغًا ويفشل كل بلاغ. أصلح ذلك باستخدام مفرد:
- في
GameManager.cs، أضف حقلًا عامًا ثابتًاInstanceمن النوع GameManager، واجعله يشير إلى هذا البرنامج النصي في Awake. - في
Meteor.cs، احذف الحقلgameوأرسل البلاغات عبرGameManager.Instanceبدلًا منه.
اضغط على Play، والتقط بعض النيازك ودع بعضها يفوتك، ثم اضغط على Check.
جرّب بنفسك
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
public TMP_Text caughtText;
public TMP_Text shieldText;
private int caught;
private int shield = 3;
public void MeteorCaught()
{
caught++;
caughtText.text = "Caught: " + caught;
}
public void MeteorLanded()
{
shield--;
shieldText.text = "Shield: " + shield;
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس بناء ألعاب حقيقية
4المشاهد والمستويات
تحميل مشهدإعادة تشغيل المستوىالمستوى التاليالاحتفاظ بالبيانات بين المشاهدمراجعة: اختيار المستوى10مشروع: لعبة منصات ثلاثية الأبعاد
المسارالمنصات المتحركة2الأزرار والشاشات
الأزرار وonClickالتعبيرات Lambdaالربط في Inspectorتشغيل اللوحات وإيقافهاأشرطة الصحةمراجعة: متجر الترقيات5الحفظ باستخدام PlayerPrefs
حفظ رقمالتحميل بقيمة افتراضيةأعلى نتيجةحفظ الإعداداتمراجعة: العملات في البنك6مشروع: عدّاء بلا نهاية
ثلاثة مساراتعوائق أمامك