Menu
CoddyTech

Interfaces et TryGetComponent

Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 7 sur 50.

TryGetComponent recherche un composant et vous indique en un seul appel s’il en a trouvé un. Il fonctionne aussi avec les interfaces, ce qui en fait la méthode habituelle pour demander à l’objet que vous avez touché s’il peut subir des dégâts. Cette mine inflige des dégâts à tout ce qui l’entoure et implémente 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 déclare la variable à l’intérieur de l’appel. TryGetComponent renvoie true et renseigne target lorsque l’objet possède un composant qui implémente IDamageable ; sinon, il renvoie false et target vaut null. Il examine uniquement cet objet, jamais son parent ni ses enfants.

GetComponent signale différemment l’absence d’une classe et celle d’une interface. Dans l’Editor, GetComponent<Rigidbody>() sur un objet sans Rigidbody renvoie le faux null de Unity : == null est vrai, mais ?. ne le détecte pas et l’appel déclenche MissingComponentException. Une interface n’a pas de faux null : GetComponent<IDamageable>() renvoie un véritable null C#, donc == null et ?. fonctionnent tous deux. TryGetComponent évite cette question dans les deux cas et n’alloue rien dans l’Editor lorsque le composant est absent.

challenge icon

Défi

Facile

La tourelle laser tourne avec les flèches gauche et droite, et la barre d’espace appelle Fire() dans Laser.cs. Écris Fire. Lance un rayon depuis la tourelle dans sa direction avant, sur une longueur de range unités (l’Inspector est réglé sur 10), puis :

  • S’il touche un objet qui possède un IDamageable, appelle TakeDamage(damage) sur cet objet et affiche Hit et le nom de l’objet dans le journal, par exemple Hit Robot.
  • Si l’objet n’a pas d’IDamageable mais possède un Rigidbody, pousse-le avec AddForce(transform.forward * push, ForceMode.Impulse) et affiche Pushed et son nom dans le journal.
  • Dans tous les autres cas, affiche Blocked by et son nom dans le journal, par exemple Blocked by Pillar. Si le rayon ne touche rien, affiche Missed dans le journal.

Utilise TryGetComponent pour les deux recherches. IDamageable.cs, Robot.cs et Balloon.cs sont prêts. Appuie sur Play et tire dans toutes les directions, puis clique sur Check.

Essayez vous-même

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()
    {
        // Lance un rayon vers l’avant, d’une longueur de range unités, et traite ce qu’il touche
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Architecture de jeu dans Unity