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

الاحتفاظ بالبيانات بين المشاهد

جزء من قسم بناء ألعاب حقيقية في رحلة 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; كل سكربت يشير إلى كائن أوشك على التدمير.

challenge icon

التحدي

سهل

ساعة لقياس زمن إنهاء اللعبة. يحسب الكائن 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"));
    }
}
quiz iconاختبر نفسك

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

جميع دروس بناء ألعاب حقيقية