Menu
CoddyTech
flag Ar iconالعربيةdown icon

الواجهات و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 صحيحة، لكن ?. لا يتعرّف عليها، ويؤدي الاستدعاء إلى رمي MissingComponentException. أما الواجهة فليس لها قيمة null زائفة: يعيد GetComponent<IDamageable>() قيمة null حقيقية في C#، لذا يعمل كل من == null و?. معها. يتجنب TryGetComponent هذه المسألة في الحالتين، ولا يخصّص أي ذاكرة في المحرر عندما يكون المكوّن غير موجود.

challenge icon

التحدي

سهل

يدور برج الليزر باستخدام السهمين الأيسر والأيمن، ويستدعي Space الدالة 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 جاهزة. اضغط Play وأطلق النار في كل اتجاه، ثم اضغط Check.

جرّب بنفسك

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