Eventos de C# no Unity
Parte da seção Arquitetura de jogos no Unity do Journey de Unity da Coddy. Lição 10 de 50.
Quando a pontuação muda, várias coisas se importam: o texto da pontuação, um som, uma conquista. Se o ScoreKeeper chamar cada uma delas, precisará de um campo para cada uma, e cada novo recurso significa editá-lo. Um evento inverte isso: o ScoreKeeper anuncia a mudança, e quem se importa se inscreve. Você conhece event e Action do C#. No Unity, o publicador e seus ouvintes são componentes, geralmente em GameObjects diferentes:
using System;
using UnityEngine;
public class ScoreKeeper : MonoBehaviour
{
public event Action<int> OnScoreChanged;
private int score;
public void AddPoints(int points)
{
score += points;
OnScoreChanged?.Invoke(score);
}
}// ScoreLabel.cs, no texto do HUD
public ScoreKeeper keeper;
public TMP_Text label;
void Start()
{
keeper.OnScoreChanged += ShowScore;
}
void ShowScore(int score)
{
label.text = "Score: " + score;
}Action<int> significa que cada ouvinte é um método que recebe um int, neste caso a nova pontuação. Invoke chama todos os métodos inscritos, na ordem em que se inscreveram. Sem ouvintes, o evento é null, então uma chamada simples como OnScoreChanged(score) lançaria uma NullReferenceException, e ?. ignora a chamada. A palavra-chave event limita os outros scripts a += e -=: em ScoreLabel, keeper.OnScoreChanged(5) ou keeper.OnScoreChanged = null não compila.
O ScoreKeeper não tem um campo para o rótulo e nem sabe que ele existe. Um contador de combo ou um reprodutor de som se inscreve da mesma forma, e o ScoreKeeper continua como está; uma cena de teste sem HUD é executada sem erros. Um ouvinte encontra o publicador por meio de uma referência no Inspector, como aqui, ou de qualquer outra forma que você conheça, como GetComponent ou um singleton. Remover um ouvinte com -= é importante quando os objetos são destruídos, assunto da próxima lição.
Desafio
FácilO combo do lutador aumenta a cada golpe com a tecla Space e volta a 0 após comboWindow (1) segundo sem um golpe. No momento, Fighter.cs define o texto do combo e o tamanho da chama por conta própria, então precisa de um campo para cada um. Inverta essa relação com um evento:
- Em
Fighter.cs, declare um evento público chamadoOnComboChangedque passe o combo (um int). Dispare o evento com o novo combo sempre que ele mudar, incluindo quando for redefinido para 0, e garanta que um golpe não cause erro quando ninguém estiver ouvindo. - Exclua os campos
comboTexteflamede Fighter e as linhas que os usam: o Fighter não sabe nada sobre o HUD. - Em
ComboText.cseComboFlame.cs, inscreva os métodosShoweGrowno evento do lutador emStart(). Ambos têm um campofighter, vinculado na cena.
Pressione Play, acerte o saco de pancadas algumas vezes com Space, espere um segundo e depois Check.
Experimente você mesmo
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;
public class Fighter : MonoBehaviour
{
public float comboWindow = 1f;
public TMP_Text comboText;
public Transform flame;
private int combo;
private float sinceHit;
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
combo++;
sinceHit = 0f;
comboText.text = "Combo x" + combo;
flame.localScale = Vector3.one * (0.5f + 0.25f * combo);
}
else if (combo > 0)
{
sinceHit += Time.deltaTime;
if (sinceHit > comboWindow)
{
combo = 0;
comboText.text = "";
flame.localScale = Vector3.one * 0.5f;
}
}
}
}
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