סינגלטון גנרי
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 43 מתוך 64.
הסינגלטון של יחידה 3 מורכב מחמש שורות שכל מנהל חוזר עליהן: Instance סטטי, Awake שמגדיר אותו ובדיקת הכפילות. מחלקת בסיס גנרית כותבת אותן פעם אחת. כל מנהל יורש ממנה ומציין את עצמו בתור הטיפוס:
public abstract class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance { get; private set; }
protected virtual void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this as T;
}
}
public class ScoreManager : Singleton<ScoreManager>
{
public int score;
public void Add(int points) { score += points; }
}
public class SoundManager : Singleton<SoundManager>
{
public void Play(string clip) { Debug.Log("Playing " + clip); }
}// בכל סקריפט
ScoreManager.Instance.Add(10);
SoundManager.Instance.Play("coin");איבר סטטי של מחלקה גנרית שייך לכל טיפוס שנוצר ממנה: Singleton<ScoreManager> ו־Singleton<SoundManager> הם שני טיפוסים, שלכל אחד מהם יש Instance משלו, כך שהמנהלים לעולם אינם חולקים אותו. הטיפוס של ScoreManager.Instance הוא כבר ScoreManager, ולשם כך נועד T. בתוך מחלקת הבסיס, this מוכר רק בתור Singleton<T>, ולכן this as T מעביר אותו בתור המנהל שהוא באמת.
מחלקת הבסיס היא אבסטרקטית: Unity מציבה על אובייקטים רק את המנהלים. מנהל שזקוק ל־Awake משלו לא צריך לכתוב void Awake() רגיל. כך הוא מסתיר את המתודה של מחלקת הבסיס (המהדר מזהיר על כך), Unity קוראת רק למתודה שלו, ו־Instance לעולם אינו מוגדר. יש לדרוס אותה ולקרוא תחילה למתודה של מחלקת הבסיס:
protected override void Awake()
{
base.Awake();
score = 0;
}אתגר
בינוניתן לשני המנהלים בסיס ששורד טעינות של סצנות.
- ב־
PersistentSingleton, כתובprotected virtual void Awake(): הראשון הופך ל־Instanceונשאר (DontDestroyOnLoad); מופע מאוחר יותר משמיד את עצמו. Walletו־MusicPlayerיורשים ממנו; מחק אתInstanceשלהם ואת Awake של Wallet.MusicPlayerדורס את Awake:base.Awake(), ואז, אם הוא ה־Instance, רושם ביומןNow playing: Adventure.
לחץ על „שחק”, בקר ביער וחזור: מטבע אחד. ואז לחץ על „בדיקה”.
נסו בעצמכם
using UnityEngine;
public abstract class PersistentSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
public static T Instance { get; private set; }
// Awake: לשמור את הראשון גם בעת טעינת סצנות, ולהשמיד כל אחד נוסף שייווצר אחריו
}
כל השיעורים ביחידה ארכיטקטורת משחקים ב-Unity
1רכיבים, לא היררכיות
רכיבים קטניםסקריפט בסיסי לאויברכיבים מופשטיםרכיבים שפועלים יחדחזרה: צריח מודולריחזרה: תותח כפול4נתונים שעברו סריאליזציה
מחלקות שניתנות לסריאליזציהרשימות ב־Inspectorטיפוסי Enum ב־Inspectorחזרה: טבלת שללהגרלת השלל2ממשקים ב-Unity
IDamageableממשקים ו-TryGetComponentGetComponentsסיכום: מקש אינטראקציהסיכום: הקרוב ביותר בטווחתרגלו בעצמכם: Unity אונליין