שמירה בין סצנות
חלק מהיחידה בונים משחקים אמיתיים במסלול ה-Unity של Coddy. שיעור 20 מתוך 56.
טעינת סצנה הורסת כל אובייקט מהסצנה הישנה, אבל יש דברים שצריכים להישאר לאורך כל המשחק, כמו המטבעות ששחקן נושא משלב לשלב. DontDestroyOnLoad(gameObject) מעביר אובייקט אל מחוץ לסצנה שלו, אל סצנה משלו, שנקראת DontDestroyOnLoad בהיררכיה בזמן Play, וטעינות אינן נוגעות בה. הפעולה פועלת רק על אובייקט שורש: על אובייקט צאצא, 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 כבר הוגדר, הורס את עצמו ועוצר, וה-session שעבר בין השלבים נשאר.
ה-return חשוב כי Destroy ממתינה עד סוף הפריים. בלעדיו, שאר Awake עדיין הייתה רצה עבור האובייקט החדש: Instance = this; היה מפנה כל סקריפט לאובייקט שעומד להיהרס.
אתגר
קלשעון למדידת זמן ריצת מהירות. האובייקט RunClock ב-Level1 סופר את השניות של הריצה כולה ומתעד פיצול בכל פעם שמסיימים שלב. אובייקט Goal המוזהב של Level1 טוען את Level2, שהיעד שלו טוען שוב את Level1, וכל יעד קורא קודם ל-RunClock.Instance.Split(). לכל שלב יש HUD משלו עם ClockText; בחלון Inspector משייכים ל-RunClock את זה שנמצא ב-Level1. החצים מזיזים את Player. שנה את 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"));
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה בונים משחקים אמיתיים
10פרויקט: משחק פלטפורמה תלת־ממדי
המסלולפלטפורמות נעות