Inscreva-se em OnEnable
Parte da seção Arquitetura de jogos no Unity do Journey de Unity da Coddy. Lição 11 de 50.
Um listener que é destruído não sai do evento por conta própria. O evento ainda mantém seu método, e a próxima chamada de Invoke o chama no componente destruído. O primeiro uso de transform nesse método lança MissingReferenceException e, como uma exceção encerra o Invoke, os listeners posteriores também são ignorados. Portanto, cada += precisa de um -=, e o par de métodos do Unity para isso é OnEnable e OnDisable:
public class Guard : MonoBehaviour
{
public Alarm alarm;
void OnEnable()
{
alarm.OnTriggered += RunTo;
}
void OnDisable()
{
alarm.OnTriggered -= RunTo;
}
void RunTo(Vector3 spot)
{
transform.LookAt(spot);
}
}O Unity chama OnDisable quando o objeto é desativado com SetActive(false), quando o script é desativado e quando o objeto é destruído, antes de OnDestroy. OnEnable é executado cada vez que ele é reativado. Com esse par, um guarda escuta exatamente enquanto está ativo: um guarda destruído deixa de fazer parte do evento, um guarda desativado para uma cena cinemática ignora o alarme e, quando é reativado, volta a escutar.
Outros dois pareamentos dão errado. Com += em Start e -= em OnDisable, um guarda desativado e reativado nunca volta a escutar, porque Start é executado apenas uma vez. Com += em OnEnable e sem -=, cada reativação adiciona RunTo novamente, e um alarme o chama duas vezes. Remover um método que não está inscrito não faz nada, então -= em OnDisable nunca precisa de uma verificação.
Desafio
FácilO sino da vila toca cada vez que você pressiona a barra de espaço (Bell.cs, pronto), e seu evento OnRing avisa os aldeões. Um aldeão dá um salto a cada toque e vai para casa depois de ringsToLeave toques: Hop o destrói. Ana vai para casa depois de 2 toques. Toque mais uma vez e o Console exibirá uma MissingReferenceException.
Corrija Villager.cs para que um aldeão escute o sino exatamente enquanto estiver ativo:
- Inscreva
Hopno evento do sino sempre que o aldeão for ativado e cancele a inscrição quando ele for desativado ou destruído. MantenhaHopeUpdatecomo estão. - Um aldeão desativado com
SetActive(false)não dá saltos. Quando for ativado novamente, ele dá um salto por toque.
Pressione Play, toque o sino quatro vezes e observe o Console; em seguida, clique em Check.
Experimente você mesmo
using UnityEngine;
public class Villager : MonoBehaviour
{
public Bell bell;
public int ringsToLeave = 3;
public int hops;
void Start()
{
bell.OnRing += Hop;
}
void Update()
{
// volta ao chão após um salto
Vector3 p = transform.position;
transform.position = new Vector3(p.x, Mathf.MoveTowards(p.y, 0.5f, 4f * Time.deltaTime), p.z);
}
void Hop(int ring)
{
hops++;
transform.position += Vector3.up * 0.8f;
if (hops == ringsToLeave)
{
Debug.Log(name + " goes home");
Destroy(gameObject);
}
}
}
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
1Componentes, não hierarquias
Componentes pequenosUm script-base para inimigosComponentes abstratosComponentes trabalhando juntosRevisão: Torre modular4Dados Serializados
Classes SerializáveisListas no InspectorEnums no InspectorRevisão: Tabela de Loot7Máquinas de Estados
Estados como ClassesUma Máquina de EstadosTransiçõesInteligências dos InimigosRevisão: Estados da Porta10Projeto: Sobrevivente da Arena
O HeróiTipos de Inimigos5ScriptableObjects
Assets de dadosAtributos das armasConfigurações compartilhadasOndas como dadosRevisão: banco de dados de itens3Eventos
Eventos de C# no UnityInscreva-se em OnEnableCampos de UnityEventEventos controlam a interfaceRevisão: janela de conquista