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.
Sfida
FacileLa 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 registraHite il nome dell’oggetto, per esempioHit Robot. - Se l’oggetto non ha un IDamageable ma ha un Rigidbody, spingilo con
AddForce(transform.forward * push, ForceMode.Impulse)e registraPushede il suo nome. - Qualsiasi altra cosa registra
Blocked bye il suo nome, per esempioBlocked by Pillar. Un raggio che non colpisce nulla registraMissed.
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
}
}
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
1Componenti, non gerarchie
Componenti piccoliUno script base per i nemiciComponenti astrattiComponenti che collaboranoRiepilogo: torretta modulare4Dati serializzati
Classi serializzabiliListe nell'InspectorEnum nell'InspectorRiepilogo: tabella del bottino7Macchine a stati
Gli stati come classiUna macchina a statiTransizioniIntelligenze dei nemiciRiepilogo: stati della porta10Progetto: Sopravvissuto nell’arena
L’eroeTipi di nemici5ScriptableObjects
Asset di datiStatistiche delle armiImpostazioni condiviseOndate come datiRiepilogo: database degli oggetti