מחלקות שניתנות לסריאליזציה
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 15 מתוך 50.
סקריפט עם הגדרות רבות מציג רשימה ארוכה ושטוחה ב-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 חדש מתחיל איתם. struct פועל באותו אופן עם המאפיין [System.Serializable] public struct Range { public float min; public float max; }, וכמו Vector3, הוא מועתק כשמשייכים אותו.
המאפיין נחוץ משום ש-Unity שומרת רק את הטיפוסים שאומרים לה לשמור. בלעדיו המחלקה אינה גלויה ב-Inspector: אין פריט מתקפל, הערכים שהוגדרו שם אינם נשמרים, ו-Unity אינה יוצרת את האובייקט, ולכן normal.speed זורק NullReferenceException. בתוך המחלקה חלים כללי ה-Inspector הרגילים: שדות public או שדות private שמסומנים ב-[SerializeField], לעולם לא מאפיינים או שדות static.
אתגר
קללפנס של החוקר יש שתי אלומות, ומקש הרווח מחליף ביניהן: אלומה רחבה וחמימה להתבוננות סביב, ואלומה ממוקדת ולבנה וקרירה שמאירה לעומק המערה. Flashlight.cs שומר את שלוש ההגדרות של כל אלומה בשישה שדות נפרדים. הסצנה כבר מוגדרת כך שההגדרות מקובצות לפי אלומה, והסקריפט צריך להתאים לכך:
- הגדירו struct בשם
Beamעם שלושה שדות ציבוריים:color(מטיפוס Color),rangeו-angle(מספרים ממשיים). הוא חייב להופיע ב-Inspector. - החליפו את ששת השדות הנפרדים בשני שדות מסוג Beam, בשם
wideו-focused. בסצנה מוגדרים ל-wide צבע חמים, טווח 6 וזווית 80, ול-focused צבע לבן וקריר, טווח 15 וזווית 25. - גרמו ל-
Apply()לקרוא את ה-Beam של האלומה הנוכחית ולהגדיר באמצעותו אתcolor, אתrangeואתspotAngleשל ה-Light. כל השאר נשאר כפי שהוא: הפנס מתחיל עם האלומה הרחבה, ומקש הרווח מחליף בין האלומות.
לחצו על Play, לחצו על מקש הרווח כדי להאיר את הקצה הרחוק של המערה, ואז לחצו על Check.
נסו בעצמכם
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רכיבים, לא היררכיות
רכיבים קטניםסקריפט בסיס לאויברכיבים מופשטיםרכיבים שעובדים יחדסיכום: צריח מודולרי