Menu
CoddyTech

Interfaces e TryGetComponent

Parte da seção Arquitetura de jogos no Unity do Journey de Unity da Coddy. Lição 7 de 50.

TryGetComponent procura um componente e informa se encontrou um, em uma única chamada. Também funciona com interfaces, o que o torna a forma usual de perguntar ao objeto atingido se ele pode receber dano. Esta mina causa dano a tudo ao redor que seja 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 declara a variável dentro da chamada. TryGetComponent retorna true e preenche target quando o objeto tem um componente que implementa IDamageable; caso contrário, retorna false e target é null. Ele verifica apenas aquele objeto, nunca o pai ou os filhos dele.

GetComponent relata a ausência de uma classe e a ausência de uma interface de formas diferentes. No Editor, GetComponent<Rigidbody>() em um objeto sem Rigidbody retorna o null falso do Unity: == null é true, mas ?. não o reconhece e a chamada lança MissingComponentException. Uma interface não tem null falso: GetComponent<IDamageable>() retorna um null real de C#, então == null e ?. funcionam com ele. TryGetComponent evita essa questão em ambos os casos e não aloca nada no Editor quando o componente está ausente.

challenge icon

Desafio

Fácil

A torre laser gira com as setas para a esquerda e para a direita, e a tecla Espaço chama Fire() em Laser.cs. Escreva Fire. Lance um raio da torre na direção para a qual ela está voltada, com comprimento de range unidades (o Inspector define 10), depois:

  • Se atingir algo que tenha um IDamageable, chame TakeDamage(damage) nele e registre Hit e o nome do objeto, como Hit Robot.
  • Se o objeto não tiver IDamageable, mas tiver um Rigidbody, empurre-o com AddForce(transform.forward * push, ForceMode.Impulse) e registre Pushed e o nome dele.
  • Qualquer outra coisa registra Blocked by e o nome dela, como Blocked by Pillar. Um raio que não atingir nada registra Missed.

Use TryGetComponent para ambas as buscas. IDamageable.cs, Robot.cs e Balloon.cs estão prontos. Pressione Jogar e atire em todas as direções, depois Verificar.

Experimente você mesmo

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 um raio para a frente, com comprimento de range unidades, e lide com o que ele atingir
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Arquitetura de jogos no Unity