Menu
CoddyTech

Interfacce e TryGetComponent

Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 7 di 50.

TryGetComponent cerca un componente e ti dice se ne ha trovato uno, con una sola chiamata. Funziona anche con le interfacce, perciò è il modo usuale per chiedere a qualunque cosa tu colpisca se può subire danni. Questa mina danneggia tutto ciò che la circonda e che 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. Controlla solo quell'oggetto, mai il suo genitore o i 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 sia == null sia ?. funzionano. TryGetComponent evita il problema in entrambi i casi e, nell'Editor, non alloca nulla quando il componente è mancante.

challenge icon

Sfida

Facile

La torre laser ruota con le frecce sinistra e destra, mentre la barra spaziatrice chiama Fire() in Laser.cs. Scrivi Fire. Lancia un raggio dalla torre nella direzione in cui è rivolta, lungo range unità (l’Inspector imposta 10), poi:

  • Se colpisce qualcosa che ha un IDamageable, chiamaci TakeDamage(damage) e registra Hit e il nome dell’oggetto, per esempio Hit Robot.
  • Se l’oggetto non ha un IDamageable ma ha un Rigidbody, spingilo con AddForce(transform.forward * push, ForceMode.Impulse) e registra Pushed e il suo nome.
  • Qualsiasi altra cosa registra Blocked by e il suo nome, per esempio Blocked by Pillar. Un raggio che non colpisce nulla registra Missed.

Usa TryGetComponent per entrambe le ricerche. IDamageable.cs, Robot.cs e Balloon.cs sono pronti. Premi Play e spara in ogni direzione, poi Check.

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
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Architettura dei giochi in Unity