الاحتفاظ بالبيانات بين المشاهد
جزء من قسم بناء ألعاب حقيقية في رحلة Unity على Coddy. الدرس 20 من 56.
يؤدي تحميل مشهد إلى تدمير كل كائنات المشهد القديم، لكن يجب أن تستمر بعض الأشياء طوال اللعبة، مثل العملات التي يحملها اللاعب من مستوى إلى آخر. تنقل DontDestroyOnLoad(gameObject) كائنًا من مشهده إلى مشهد خاص به، يُسمى DontDestroyOnLoad في التسلسل الهرمي أثناء التشغيل، ولا تؤثر فيه عمليات التحميل. تعمل هذه الطريقة على الكائن الجذر فقط: أما إذا استُخدمت على كائن فرعي، فسيسجل Unity تحذيرًا ولن يُبقي أي شيء. تأتي الكائنات الفرعية للكائن المُبقى معه، لكن الكائنات التي يشير إليها فقط لا تأتي معه: بعد التحميل، سيحتوي الحقل الذي كان يشير إلى كائن من المشهد القديم على كائن مُدمّر، وتكون نتيجة مقارنته بـ null مساوية.
public class GameSession : MonoBehaviour
{
public static GameSession Instance;
public int coins;
void Awake()
{
if (Instance != null)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
}يعيش هذا GameSession في مشهد Menu. ينتقل التشغيل من Menu إلى Level1، ثم يعود إلى Menu، فيعيد Menu إنشاء جميع كائناته، بما في ذلك GameSession جديد، بينما يظل الكائن المُبقى موجودًا. من دون التحقق في Awake، سيكون هناك كائنان، وسيتولى الكائن الجديد Instance بقيمة 0 من العملات. أما مع وجوده، فيجد الكائن الجديد أن Instance مضبوط مسبقًا، فيدمّر نفسه ويتوقف، وتبقى جلسة اللعب التي اجتازت المستويات.
تُعد return مهمة لأن Destroy ينتظر حتى نهاية الإطار. ومن دونها، سيظل بقية Awake يُنفّذ للكائن الجديد: ستجعل Instance = this; كل سكربت يشير إلى كائن أوشك على التدمير.
التحدي
سهلساعة لقياس زمن إنهاء اللعبة. يحسب الكائن RunClock في Level1 ثواني الجولة كاملة ويسجّل زمنًا جزئيًا عند كل مرة يُنهى فيها مستوى. ينقل هدف الذهب في Level1 اللاعب إلى Level2، وينقل هدفه اللاعب إلى Level1 مجددًا، ويستدعي كل هدف RunClock.Instance.Split() أولًا. لكل مستوى واجهة HUD خاصة به تحتوي على ClockText؛ ويُعيّن Inspector إلى RunClock العنصر الموجود في Level1. تحرّك الأسهم اللاعب. غيّر RunClock.cs بحيث:
- تستمر الساعة في العمل خلال كل عملية تحميل لمشهد، من دون أن تبدأ من جديد؛
- يظهر الوقت دائمًا في
ClockTextالخاص بالمستوى المفتوح، بالشكلTime: 12.3؛ - عند العودة إلى Level1، الذي يحتوي على RunClock خاص به، تظل هناك ساعة واحدة، وهي الساعة التي كانت تعمل، وتكون
RunClock.Instanceهي تلك الساعة.
اضغط Play، وانتقل إلى Level2 ثم عُد، وأنهِ Level1 مرة أخرى، ثم اضغط Check.
جرّب بنفسك
using UnityEngine;
using TMPro;
public class RunClock : MonoBehaviour
{
public static RunClock Instance;
public TMP_Text clockText;
private float seconds;
void Awake()
{
Instance = this;
}
void Update()
{
seconds += Time.deltaTime;
clockText.text = "Time: " + seconds.ToString("0.0");
}
public void Split()
{
Debug.Log("Split: " + seconds.ToString("0.0"));
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس بناء ألعاب حقيقية
4المشاهد والمستويات
تحميل مشهدإعادة تشغيل المستوىالمستوى التاليالاحتفاظ بالبيانات بين المشاهدمراجعة: اختيار المستوى10مشروع: لعبة منصات ثلاثية الأبعاد
المسارالمنصات المتحركة2الأزرار والشاشات
الأزرار وonClickالتعبيرات Lambdaالربط في Inspectorتشغيل اللوحات وإيقافهاأشرطة الصحةمراجعة: متجر الترقيات5الحفظ باستخدام PlayerPrefs
حفظ رقمالتحميل بقيمة افتراضيةأعلى نتيجةحفظ الإعداداتمراجعة: العملات في البنك6مشروع: عدّاء بلا نهاية
ثلاثة مساراتعوائق أمامك