Menu
CoddyTech

אירועי C# ב-Unity

חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 10 מתוך 50.

כשהניקוד משתנה, כמה דברים מושפעים מכך: טקסט הניקוד, צליל, הישג. אם ScoreKeeper קורא לכל אחד מהם, הוא צריך שדה עבור כל אחד, וכל תכונה חדשה מחייבת לערוך אותו. אירוע הופך את הכיוון: ScoreKeeper מודיע על השינוי, ומי שזה חשוב לו נרשם כמנוי. את event ואת Action את/ה מכיר/ה מ-C#. ב-Unity המפרסם והמאזינים הם רכיבים, בדרך כלל באובייקטים שונים של GameObject:

using System;
using UnityEngine;

public class ScoreKeeper : MonoBehaviour
{
    public event Action<int> OnScoreChanged;
    private int score;

    public void AddPoints(int points)
    {
        score += points;
        OnScoreChanged?.Invoke(score);
    }
}
// ScoreLabel.cs, על הטקסט של ה-HUD
public ScoreKeeper keeper;
public TMP_Text label;

void Start()
{
    keeper.OnScoreChanged += ShowScore;
}

void ShowScore(int score)
{
    label.text = "Score: " + score;
}

Action<int> פירושו שכל מאזין הוא מתודה שמקבלת int אחד, ובמקרה הזה את הניקוד החדש. Invoke קורא לכל המתודות שנרשמו כמנויות, לפי סדר ההרשמה. ללא מאזינים, האירוע הוא null, ולכן קריאה רגילה ל-OnScoreChanged(score) תגרום ל-NullReferenceException, ואילו ?. מדלג על הקריאה במקום זאת. מילת המפתח event מגבילה סקריפטים אחרים ל-+= ול--=: ב-ScoreLabel, keeper.OnScoreChanged(5) או keeper.OnScoreChanged = null לא יתקמפלו.

ל-ScoreKeeper אין שדה עבור התווית והוא לא יודע שהיא קיימת. מונה קומבו או נגן צלילים יכולים להירשם כמנויים באותה דרך, ו-ScoreKeeper נשאר כפי שהוא; סצנת בדיקה ללא HUD פועלת ללא שגיאות. מאזין מאתר את המפרסם באמצעות הפניה ב-Inspector, כמו כאן, או בכל דרך אחרת שמוכרת לך, כגון GetComponent או singleton. הסרת מאזין באמצעות -= חשובה ברגע שאובייקטים מושמדים, וזה הנושא של השיעור הבא.

challenge icon

אתגר

קל

השילוב של הלוחם גדל עם כל לחיצה על Space, וחוזר ל-0 לאחר comboWindow (שנייה אחת) ללא פגיעה. כרגע Fighter.cs קובע בעצמו את טקסט השילוב ואת גודל הלהבה, ולכן הוא זקוק לשדה עבור כל אחד מהם. שנה את הגישה באמצעות אירוע:

  • ב-Fighter.cs, הכרז על אירוע ציבורי בשם OnComboChanged שמעביר את השילוב (מספר שלם). הפעל אותו עם השילוב החדש בכל פעם שהשילוב משתנה, כולל האיפוס ל-0, וודא שפגיעה לא גורמת לשגיאה כשאף אחד לא מאזין.
  • מחק את השדות comboText ו-flame של Fighter ואת השורות שמשתמשות בהם: Fighter לא יודע דבר על ה-HUD.
  • ב-ComboText.cs וב-ComboFlame.cs, הירשם לאירוע של הלוחם עם המתודות Show ו-Grow בתוך Start(). לשניהם יש שדה fighter, שמקושר בסצנה.

לחץ על Play, פגע בשק עם Space כמה פעמים, המתן שנייה, ואז לחץ על Check.

נסו בעצמכם

using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;

public class Fighter : MonoBehaviour
{
    public float comboWindow = 1f;
    public TMP_Text comboText;
    public Transform flame;
    private int combo;
    private float sinceHit;

    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame)
        {
            combo++;
            sinceHit = 0f;
            comboText.text = "Combo x" + combo;
            flame.localScale = Vector3.one * (0.5f + 0.25f * combo);
        }
        else if (combo > 0)
        {
            sinceHit += Time.deltaTime;
            if (sinceHit > comboWindow)
            {
                combo = 0;
                comboText.text = "";
                flame.localScale = Vector3.one * 0.5f;
            }
        }
    }
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה ארכיטקטורת משחקים ב-Unity