אירועים מניעים את ממשק המשתמש
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 15 מתוך 64.
באמצעות אירועים, ה-HUD עוקב אחר המשחק, בעוד שלמשחק אין שום מידע על ה-HUD. רכיב Health מנהל את נקודות החיים ומודיע על שני דברים: החיים השתנו, והם הגיעו ל-0. אין בו שדה עבור מד, טקסט או מסך סיום משחק, ולכן אותו רכיב פועל על השחקן, על אויב שאין לו HUD וגם בסצנת בדיקה:
public class Health : MonoBehaviour
{
public int maxHp = 100;
public event Action<int, int> OnChanged;
public event Action OnDied;
public int Hp { get; private set; }
void Awake()
{
Hp = maxHp;
}
public void TakeDamage(int amount)
{
if (Hp == 0) return;
Hp = Mathf.Max(Hp - amount, 0);
OnChanged?.Invoke(Hp, maxHp);
if (Hp == 0) OnDied?.Invoke();
}
}// HealthBar.cs, על גבי ה-HUD
public Health health;
public Image bar;
void OnEnable() { health.OnChanged += Show; }
void OnDisable() { health.OnChanged -= Show; }
void Start()
{
Show(health.Hp, health.maxHp);
}
void Show(int hp, int max)
{
bar.fillAmount = (float)hp / max;
}המד מאזין רק כשהוא פעיל, באמצעות צמד הפונקציות OnEnable ו-OnDisable. האירוע מעביר את שני המספרים, ולכן Show לא זקוקה לשום דבר נוסף מ-Health. GameOverScreen נרשם ל-OnDied כדי להציג את הלוח שלו, וצליל פגיעה נרשם ל-OnChanged, כל אחד בסקריפט משלו, ורכיב Health אינו משתנה עבור אף אחד מהם. Hp { get; private set; } מאפשר ל-HUD לקרוא את החיים, אך לא לשנות אותם.
אירוע מדווח על שינויים, ולכן לפני הפגיעה הראשונה המד לא שמע דבר. הוא מציג את החיים הנוכחיים פעם אחת, ב-Start. לא ב-OnEnable: Unity קוראת ל-Awake ואז ל-OnEnable עבור כל אובייקט בנפרד, בסדר לא מובטח, ולכן ייתכן שה-OnEnable של המד יפעל לפני שה-Awake של Health הגדיר את Hp, והמד יציג 0. עד שכל פונקציית Start מופעלת, כל פונקציות Awake כבר הופעלו.
אתגר
קלגרמו לאקדח לדווח על השינויים שלו, ול־HUD להאזין.
- ב־
Gun.cs, הוסיפוusing System;, אתpublic event Action<int, int> OnAmmoChangedואתpublic event Action<bool> OnReloading; העלו אותם במקומות שמצוינים בהערות. - ב־
AmmoHud.cs, הירשמו ב־OnEnableובטלו את ההרשמה ב־OnDisable:ammoTextמציג אתAmmo: 4/6, ו־reloadTextמוצג רק בזמן טעינה מחדש. - ב־
Start, הציגו פעם אחת אתgun.Ammoואתgun.Reloading.
לחצו על "שחק" ורוקנו את המחסנית פעמיים. לאחר מכן לחצו על "בדיקה".
נסו בעצמכם
using UnityEngine;
using TMPro;
public class AmmoHud : MonoBehaviour
{
public Gun gun;
public TMP_Text ammoText;
public GameObject reloadText;
}
כל השיעורים ביחידה ארכיטקטורת משחקים ב-Unity
1רכיבים, לא היררכיות
רכיבים קטניםסקריפט בסיסי לאויברכיבים מופשטיםרכיבים שפועלים יחדחזרה: צריח מודולריחזרה: תותח כפול4נתונים שעברו סריאליזציה
מחלקות שניתנות לסריאליזציהרשימות ב־Inspectorטיפוסי Enum ב־Inspectorחזרה: טבלת שללהגרלת השלל2ממשקים ב-Unity
IDamageableממשקים ו-TryGetComponentGetComponentsסיכום: מקש אינטראקציהסיכום: הקרוב ביותר בטווח3אירועים
אירועי C# ב-Unityהרשמה ב-OnEnableשדות UnityEventאירועים מניעים את ממשק המשתמשחזרה: חלון קופץ להישגחזרה: טיימר החלון הקופץתרגלו בעצמכם: Unity אונליין