Menu
CoddyTech

Interfacce e TryGetComponent

Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 8 di 64.

TryGetComponent cerca un componente e ti dice se lo ha trovato, con una sola chiamata. Funziona anche con le interfacce, quindi è il metodo abituale per chiedere a qualunque oggetto colpito se può subire danni. Questa mina danneggia tutto ciò che la circonda e implementa 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 dichiara la variabile all'interno della chiamata. TryGetComponent restituisce true e assegna un valore a target quando l'oggetto ha un componente che implementa IDamageable; altrimenti restituisce false e target è null. Cerca solo su quell'oggetto, mai sul suo genitore o sui suoi figli.

GetComponent segnala in modo diverso l'assenza di una classe e quella di un'interfaccia. Nell'Editor, GetComponent<Rigidbody>() su un oggetto senza Rigidbody restituisce il null fittizio di Unity: == null è true, ma ?. non lo rileva e la chiamata genera MissingComponentException. Un'interfaccia non ha un null fittizio: GetComponent<IDamageable>() restituisce un vero null di C#, quindi == null e ?. funzionano entrambi. TryGetComponent evita il problema in entrambi i casi e, nell'Editor, non alloca nulla quando manca il componente.

challenge icon

Sfida

Facile

Scrivi Fire() in Laser: un raggio, quattro esiti.

  1. Lancia Physics.Raycast dalla torre lungo transform.forward, per una distanza pari a range. Se manca il bersaglio, registra Missed.
  2. Se hit.collider.TryGetComponent(out IDamageable target), chiama TakeDamage(damage) e registra "Hit " + hit.collider.name.
  3. Altrimenti, se ha un Rigidbody, applica AddForce(transform.forward * push, ForceMode.Impulse) e registra "Pushed " seguito dal nome; altrimenti "Blocked by " seguito dal nome.

Premi «Gioca», gira e spara in ogni direzione. Poi premi «Verifica».

Provalo tu

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()
    {
        // Lancia un raggio in avanti, lungo range unità, e gestisci ciò che colpisce
    }
}

Tutte le lezioni di Architettura dei giochi in Unity

Esercitati da solo: Playground Unity