הרשמה ב-OnEnable
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 13 מתוך 64.
מאזין שנהרס אינו יוצא מהאירוע מעצמו. האירוע עדיין מחזיק את המתודה שלו, והקריאה הבאה ל־Invoke מפעילה אותה ברכיב שנהרס. השימוש הראשון ב־transform במתודה זו זורק MissingReferenceException, ומכיוון שחריגה מסיימת את Invoke, גם המאזינים שאחריה מדולגים. לכן לכל += צריך להיות -=, וצמד המתודות של Unity לכך הוא OnEnable ו־OnDisable:
public class Guard : MonoBehaviour
{
public Alarm alarm;
void OnEnable()
{
alarm.OnTriggered += RunTo;
}
void OnDisable()
{
alarm.OnTriggered -= RunTo;
}
void RunTo(Vector3 spot)
{
transform.LookAt(spot);
}
}Unity קוראת ל־OnDisable כשהאובייקט מושבת באמצעות SetActive(false), כשהסקריפט מושבת וכשהאובייקט נהרס, לפני OnDestroy. OnEnable מופעלת בכל פעם שהאובייקט חוזר לפעול. בעזרת הצמד הזה, שומר מאזין בדיוק כל עוד הוא פעיל: שומר שנהרס מוסר מהאירוע, שומר שהושבת עבור קטע מעבר מתעלם מהאזעקה, וברגע שהוא מופעל שוב הוא מאזין שוב.
שני צימודים אחרים גורמים לבעיות. עם += ב־Start ו־-= ב־OnDisable, שומר שהושבת והופעל מחדש לעולם לא יאזין שוב, כי Start מופעלת רק פעם אחת. עם += ב־OnEnable וללא -=, כל חזרה מוסיפה שוב את RunTo, ואז אזעקה אחת קוראת לה פעמיים. הסרה של מתודה שאינה רשומה לא עושה דבר, ולכן לעולם אין צורך בבדיקה לפני -= ב־OnDisable.
אתגר
קליש לגרום לכל תושב להאזין לפעמון רק כשהוא פעיל.
- ב־
Villager.cs, העבירו אתbell.OnRing += Hop;מ־Start()אלvoid OnEnable()חדש, ומחקו אתStart(). - הוסיפו
void OnDisable()עםbell.OnRing -= Hop;. בלחיצה על „בדיקה” מכבים ומפעילים את Cleo כדי לבדוק זאת.
לחצו על „שחק” והפעילו את הפעמון ארבע פעמים: Ana חוזרת הביתה אחרי הצלצול השני, ולא מופיעה שגיאה. לאחר מכן לחצו על „בדיקה”.
נסו בעצמכם
using UnityEngine;
public class Villager : MonoBehaviour
{
public Bell bell;
public int ringsToLeave = 3;
public int hops;
void Start()
{
bell.OnRing += Hop;
}
void Update()
{
// ליפול בחזרה לקרקע אחרי קפיצה
Vector3 p = transform.position;
transform.position = new Vector3(p.x, Mathf.MoveTowards(p.y, 0.5f, 4f * Time.deltaTime), p.z);
}
void Hop(int ring)
{
hops++;
transform.position += Vector3.up * 0.8f;
if (hops == ringsToLeave)
{
Debug.Log(name + " goes home");
Destroy(gameObject);
}
}
}
כל השיעורים ביחידה ארכיטקטורת משחקים ב-Unity
1רכיבים, לא היררכיות
רכיבים קטניםסקריפט בסיסי לאויברכיבים מופשטיםרכיבים שפועלים יחדחזרה: צריח מודולריחזרה: תותח כפול4נתונים שעברו סריאליזציה
מחלקות שניתנות לסריאליזציהרשימות ב־Inspectorטיפוסי Enum ב־Inspectorחזרה: טבלת שללהגרלת השלל2ממשקים ב-Unity
IDamageableממשקים ו-TryGetComponentGetComponentsסיכום: מקש אינטראקציהסיכום: הקרוב ביותר בטווחתרגלו בעצמכם: Unity אונליין