הסינגלטון
חלק מהיחידה בונים משחקים אמיתיים במסלול ה-Unity של Coddy. שיעור 13 מתוך 56.
הפניה דרך Inspector צריכה אובייקט שאפשר לגרור אליה. אויבים ש־spawner יוצר במהלך המשחק מגיעים מ־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, על ה-prefab של האויב
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 בעצמו; בפרק ״סצנות ושלבים״ מוסבר איך למנוע את זה.
אתגר
קלמטאורים יורדים מהשמיים. ה־Spawner משגר Meteor מתוך prefab כל 1.5 שניות, החצים מזיזים את ה־Player, וה־GameManager סופר תפיסה באמצעות MeteorCaught() ומטאור שפוגע בקרקע באמצעות MeteorLanded(). הסקריפטים האלה מוכנים.
הסקריפט Meteor מדווח באמצעות השדה game שלו, אבל המטאורים נוצרים מתוך prefab, ולכן game ריק וכל דיווח נכשל. תקן את זה באמצעות singleton:
- ב־
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;
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה בונים משחקים אמיתיים
10פרויקט: משחק פלטפורמה תלת־ממדי
המסלולפלטפורמות נעות2כפתורים ומסכים
כפתורים ו-onClickביטויי למבדהחיבור ב-Inspectorהפעלה וכיבוי של פאנליםפסי בריאותסיכום: חנות שדרוגים