Menu
CoddyTech

שמירה בין סצנות

חלק מהיחידה בניית משחקים אמיתיים במסלול ה-Unity של Coddy. שיעור 20 מתוך 60.

טעינת סצנה משמידה כל אובייקט מהסצנה הקודמת, אבל יש דברים שחייבים להישאר לאורך כל המשחק, כמו המטבעות ששחקן נושא משלב לשלב. DontDestroyOnLoad(gameObject) מעביר אובייקט אל מחוץ לסצנה שלו, לסצנה משלו, שנקראת DontDestroyOnLoad בחלונית Hierarchy בזמן "שחק", וטעינות לא משפיעות עליה. הפעולה עובדת רק על אובייקט שורש: כשמפעילים אותה על אובייקט צאצא, 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

אתגר

קל

השאר שעון אחד של הריצה פועל לאורך כל טעינת סצנה.

  1. ב־Awake(), אם Instance != null, קרא ל־Destroy(gameObject); ואז ל־return;. אחרת, הגדר את Instance וקרא ל־DontDestroyOnLoad(gameObject);.
  2. טעינה הורסת את הטקסט של השלב הקודם, לכן ב־Update(), לפני שורת הטקסט, כאשר clockText == null, הגדר את clockText = GameObject.Find("ClockText").GetComponent<TMP_Text>();.

לחץ על "שחק", עבור אל Level2 וחזור: שעון אחד ממשיך לספור. לאחר מכן לחץ על "בדיקה".

נסו בעצמכם

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"));
    }
}

כל השיעורים ביחידה בניית משחקים אמיתיים

תרגלו בעצמכם: Unity אונליין