מחלקות שניתנות לסריאליזציה
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 18 מתוך 64.
סקריפט עם הגדרות רבות מציג ב־Inspector רשימה ארוכה ושטוחה. מחלקת C# רגילה יכולה לקבץ אותן: סמנו אותה ב־[System.Serializable], ושדה מהמחלקה הזו יוצג כפריט נפתח ששמו כשם השדה, ובתוכו השדות של המחלקה. מחלקה אחת יכולה לשמש כמה שדות וכמה סקריפטים:
[System.Serializable]
public class Stats
{
public float speed = 2f;
public int damage = 10;
}
public class Enemy : MonoBehaviour
{
public Stats normal;
public Stats enraged;
private Stats current;
void Start()
{
current = normal;
}
void Update()
{
transform.Translate(0f, 0f, current.speed * Time.deltaTime);
}
public void Enrage()
{
current = enraged;
}
}ב־Inspector מוצגים שני פריטים נפתחים, Normal ו־Enraged, ובכל אחד מהם Speed ו־Damage. לכל Enemy יש שני אובייקטים משלו מסוג Stats, שהערכים שלהם מוגדרים ב־Inspector שלו, והקוד ניגש אליהם כך: normal.speed. Unity יוצרת את האובייקטים האלה כשהיא טוענת את הסקריפט, לכן normal אף פעם אינו null גם בלי = new Stats(), ומאתחלי השדות (2 ו־10) הם הערכים שאיתם Enemy חדש מתחיל. מבנה פועל באותו אופן עם המאפיין, [System.Serializable] public struct Range { public float min; public float max; }, וכמו Vector3, הוא מועתק בעת השמה.
המאפיין נחוץ כי Unity שומרת רק טיפוסים שהורו לה לשמור. בלעדיו המחלקה אינה גלויה ב־Inspector: אין פריט נפתח, ערכים שמוגדרים שם אינם נשמרים, ו־Unity אינה יוצרת את האובייקט, ולכן normal.speed זורק NullReferenceException. בתוך המחלקה חלים כללי Inspector הרגילים: שדות ציבוריים או שדות פרטיים עם [SerializeField], לעולם לא מאפיינים או שדות סטטיים.
אתגר
קלקבץ את ההגדרות של כל אלומה במבנה אחד.
- מעל
Flashlight, הכרז עלpublic struct BeamעםColor color,float rangeו־float angleציבוריים. סמן אותו ב־[System.Serializable]כדי שהוא יוצג ב־Inspector. - החלף את ששת השדות הנפרדים ב־
public Beam wide;וב־public Beam focused;. - בתוך
Apply(), הגדר את שלושת הערכים של האור מתוךfocusedOn ? focused : wide.
לחץ על "שחק" ועל מקש הרווח: האלומה מגיעה אל הגביש. לאחר מכן לחץ על "בדיקה".
נסו בעצמכם
using UnityEngine;
using UnityEngine.InputSystem;
public class Flashlight : MonoBehaviour
{
public Color wideColor = Color.white;
public float wideRange = 5f;
public float wideAngle = 60f;
public Color focusedColor = Color.white;
public float focusedRange = 10f;
public float focusedAngle = 30f;
private bool focusedOn;
private Light lamp;
void Start()
{
lamp = GetComponent<Light>();
Apply();
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
focusedOn = !focusedOn;
Apply();
}
}
void Apply()
{
lamp.color = focusedOn ? focusedColor : wideColor;
lamp.range = focusedOn ? focusedRange : wideRange;
lamp.spotAngle = focusedOn ? focusedAngle : wideAngle;
}
}
כל השיעורים ביחידה ארכיטקטורת משחקים ב-Unity
1רכיבים, לא היררכיות
רכיבים קטניםסקריפט בסיסי לאויברכיבים מופשטיםרכיבים שפועלים יחדחזרה: צריח מודולריחזרה: תותח כפול4נתונים שעברו סריאליזציה
מחלקות שניתנות לסריאליזציהרשימות ב־Inspectorטיפוסי Enum ב־Inspectorחזרה: טבלת שללהגרלת השלל2ממשקים ב-Unity
IDamageableממשקים ו-TryGetComponentGetComponentsסיכום: מקש אינטראקציהסיכום: הקרוב ביותר בטווחתרגלו בעצמכם: Unity אונליין