אירועים מניעים את ממשק המשתמש
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 13 מתוך 50.
בעזרת אירועים, ה-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 כבר פעלו.
אתגר
קלמטווח ירי. מקש הרווח יורה באקדח (Gun.cs), שמכיל maxAmmo (6) יריות, וירי הירייה האחרונה מתחיל טעינה מחדש שנמשכת reloadTime (1.5) שניות וממלאת אותו שוב. ה-HUD עדיין לא מציג שום דבר מזה. גרום לאקדח להודיע על השינויים שלו ול-HUD להאזין; לאקדח לא יתווסף שדה עבור ה-HUD.
- ב-
Gun.cs, הוסף שני אירועים ציבוריים:OnAmmoChanged, שמעביר את התחמושת ואתmaxAmmo(שני int), ו-OnReloading, שמעביר bool: true כשהטעינה מחדש מתחילה, ו-false כשהיא מסתיימת. הפעל אותם במקומות שמצוינים בהערות. - ב-
AmmoHud.cs(שנמצא ב-HUD), האזן לשני האירועים כל עוד ה-HUD פעיל.ammoTextמציג את התחמושת כך:Ammo: 4/6, ו-reloadText(האובייקט עם הטקסטReloading...) מוצג רק במהלך טעינה מחדש. - ה-HUD מציג את המצב הנכון כבר בהתחלה, לפני הירייה הראשונה:
Ammo: 6/6וללא טקסט טעינה מחדש. המאפייניםAmmoו-Reloadingשל האקדח מספקים את הערכים הנוכחיים. - אם ה-HUD מושמד, האקדח ממשיך לירות בלי שגיאות.
לחץ על Play, רוקן את המחסנית פעמיים, ואז לחץ על Check.
נסו בעצמכם
using UnityEngine;
using TMPro;
public class AmmoHud : MonoBehaviour
{
public Gun gun;
public TMP_Text ammoText;
public GameObject reloadText;
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה ארכיטקטורת משחקים ב-Unity
1רכיבים, לא היררכיות
רכיבים קטניםסקריפט בסיס לאויברכיבים מופשטיםרכיבים שעובדים יחדסיכום: צריח מודולרי3אירועים
אירועי C# ב-Unityהירשם ב-OnEnableשדות UnityEventאירועים מניעים את ממשק המשתמשסיכום: חלונית הישג