الواجهات و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 هذه المسألة في الحالتين، ولا يخصّص أي ذاكرة في المحرر عندما يكون المكوّن غير موجود.
التحدي
سهليدور برج الليزر باستخدام السهمين الأيسر والأيمن، ويستدعي 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 وحدة، وتعامل مع ما يصطدم به
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس هندسة الألعاب في Unity
1المكوّنات لا التسلسلات الهرمية
مكوّنات صغيرةسكربت أساسي للعدومكوّنات مجرّدةتعمل المكوّنات معًامراجعة: برج دفاعي معياري4البيانات المتسلسلة
الأصناف القابلة للتسلسلالقوائم في Inspectorالتعدادات في Inspectorمراجعة: جدول الغنائم10مشروع: الناجي في الساحة
البطلأنواع الأعداء