Menu
CoddyTech

ממשקים ו-TryGetComponent

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

TryGetComponent מחפשת רכיב ומודיעה לך אם היא מצאה אותו, בקריאה אחת. היא עובדת גם עם ממשקים, ולכן זו הדרך המקובלת לשאול את מה שפגעת בו אם אפשר לפגוע בו. המוקש הזה פוגע בכל מה שסביבו ומממש את IDamageable:

public class Mine : MonoBehaviour
{
    public float radius = 3f;
    public int damage = 5;

    void OnTriggerEnter(Collider other)
    {
        foreach (Collider c in Physics.OverlapSphere(transform.position, radius))
        {
            if (c.TryGetComponent(out IDamageable target))
            {
                target.TakeDamage(damage);
            }
        }
        Destroy(gameObject);
    }
}

out IDamageable target מצהירה על המשתנה בתוך הקריאה. TryGetComponent מחזירה true וממלאת את target כאשר לאובייקט יש רכיב שמממש את IDamageable; אחרת היא מחזירה false ו-target הוא null. היא בודקת רק את האובייקט הזה, ולא את ההורה או הילדים שלו.

GetComponent מדווחת באופן שונה על מחלקה חסרה ועל ממשק חסר. בעורך, GetComponent<Rigidbody>() על אובייקט שאין לו Rigidbody מחזירה null מזויף של Unity: == null הוא true, אבל ?. לא מזהה אותו והקריאה זורקת MissingComponentException. לממשק אין null מזויף: GetComponent<IDamageable>() מחזירה null אמיתי של C#, ולכן גם == null וגם ?. פועלים עליו. TryGetComponent מייתרת את הצורך לבדוק זאת בשני המקרים, והיא לא מקצה זיכרון בעורך כשהרכיב חסר.

challenge icon

אתגר

קל

מגדל הלייזר מסתובב באמצעות החצים שמאלה וימינה, ומקש הרווח מפעיל את Fire() שבקובץ Laser.cs. כתבו את Fire. שגרו קרן מהמגדל בכיוון שאליו הוא פונה, באורך של range יחידות (החלונית Inspector קובעת את הערך ל-10), ואז:

  • אם הקרן פוגעת במשהו שיש לו IDamageable, קראו לו ל-TakeDamage(damage) ורשמו ביומן את Hit ואת שם האובייקט, למשל Hit Robot.
  • אם לדבר אין IDamageable אבל יש לו Rigidbody, דחפו אותו באמצעות AddForce(transform.forward * push, ForceMode.Impulse) ורשמו ביומן את Pushed ואת שמו.
  • כל דבר אחר רושם ביומן את Blocked by ואת שמו, למשל Blocked by Pillar. קרן שלא פוגעת בכלום רושמת ביומן Missed.

השתמשו ב-TryGetComponent בשתי הבדיקות. הקבצים IDamageable.cs, Robot.cs ו-Balloon.cs מוכנים. לחצו על הפעלה וירו לכל הכיוונים, ואז לחצו על בדיקה.

נסו בעצמכם

using UnityEngine;
using UnityEngine.InputSystem;

public class Laser : MonoBehaviour
{
    public float range = 10f;
    public int damage = 1;
    public float push = 5f;
    public float turnSpeed = 90f;

    private InputAction moveAction;

    void Start()
    {
        moveAction = InputSystem.actions.FindAction("Move");
    }

    void Update()
    {
        float turn = moveAction.ReadValue<Vector2>().x;
        transform.Rotate(0f, turn * turnSpeed * Time.deltaTime, 0f);
        if (Keyboard.current.spaceKey.wasPressedThisFrame)
        {
            Fire();
        }
    }

    void Fire()
    {
        // שגר קרן קדימה באורך range יחידות, וטפל במה שהיא פוגעת בו
    }
}
quiz iconבחנו את עצמכם

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

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