O Singleton
Parte da seção Criando jogos de verdade do Journey de Unity da Coddy. Lição 13 de 56.
Uma referência no Inspector precisa de algo para onde arrastar. Os inimigos que um gerador cria durante o jogo vêm de um prefab, e um prefab só pode apontar para assets e para suas próprias partes, nunca para um objeto em uma cena, então o campo GameManager deles fica vazio. A solução usual é um singleton: o GameManager armazena a si mesmo em um campo que todo script pode acessar pelo nome da classe.
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
private int kills;
void Awake()
{
Instance = this;
}
public void EnemyDown()
{
kills++;
Debug.Log("Kills: " + kills);
}
}// Enemy.cs, no prefab do inimigo
public void Die()
{
GameManager.Instance.EnemyDown();
Destroy(gameObject);
}static significa que o campo pertence à classe, não a um objeto. Cada objeto GameManager teria seu próprio kills, mas há apenas um Instance no jogo inteiro, e você o acessa pelo nome da classe: GameManager.Instance. Qualquer script pode lê-lo, inclusive um inimigo gerado há um minuto, sem precisar preencher um campo próprio.
O gerenciador define Instance = this; em Awake, onde this é o próprio script. O Unity executa todos os Awake na cena antes de qualquer Start, então outros scripts podem usar GameManager.Instance a partir de seus Start. Um segundo GameManager na cena sobrescreveria Instance com ele mesmo; o capítulo Scenes and Levels mostra como impedir isso.
Desafio
FácilChuva de meteoros. O Spawner solta um Meteor de um prefab a cada 1.5 segundos, as setas movem o Player, e o GameManager conta uma captura com MeteorCaught() e um meteoro que atinge o chão com MeteorLanded(). Esses scripts estão prontos.
O script Meteor reporta por meio do campo game, mas os meteoros vêm de um prefab, então game está vazio e todos os reports falham. Corrija isso com um singleton:
- Em
GameManager.cs, adicione um campo público estáticoInstancedo tipo GameManager e defina-o como este script em Awake. - Em
Meteor.cs, exclua o campogamee reporte por meio deGameManager.Instance.
Pressione Play, capture alguns meteoros e deixe outros passarem, depois Check.
Experimente você mesmo
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
public TMP_Text caughtText;
public TMP_Text shieldText;
private int caught;
private int shield = 3;
public void MeteorCaught()
{
caught++;
caughtText.text = "Caught: " + caught;
}
public void MeteorLanded()
{
shield--;
shieldText.text = "Shield: " + shield;
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Criando jogos de verdade
1Texto na tela
Canvas e textoExiba a pontuaçãoFormate númerosUm cronômetro regressivoRevisão: velocímetro4Cenas e Fases
Carregar uma CenaReiniciar a FasePróxima FaseManter entre CenasRevisão: Seleção de Fases10Projeto: Jogo de Plataforma 3D
O PercursoPlataformas Móveis2Botões e telas
Botões e onClickLambdasConectando no InspectorPainéis ligados e desligadosBarras de vidaRevisão: Loja de melhorias5Salvando com PlayerPrefs
Salvar um númeroCarregar com um valor padrãoRecordeSalvar configuraçõesRevisão: Moedas no banco3O Gerenciador do Jogo
Um Script Controla o JogoO SingletonEstados do JogoAlternando o EstadoRevisão: Gerenciador de Rodadas6Projeto: Corredor Infinito
Três FaixasObstáculos à Frente