Menu
CoddyTech

O Singleton

Parte da seção Criando Jogos de Verdade do Journey de Unity da Coddy. Lição 13 de 60.

Uma referência do Inspector precisa de algo para receber o objeto arrastado. Os inimigos que um spawner 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 todo, e você o acessa pelo nome da classe: GameManager.Instance. Qualquer script pode lê-lo, inclusive um inimigo criado há um minuto, sem precisar preencher nenhum campo próprio.

O gerenciador define Instance = this; em Awake, onde this é o próprio script. O Unity executa todos os Awake da cena antes de qualquer Start, então outros scripts podem usar GameManager.Instance a partir do próprio Start. Um segundo GameManager na cena sobrescreveria Instance com ele mesmo; o capítulo Cenas e níveis mostra como impedir isso.

challenge icon

Desafio

Fácil

Faça com que os meteoros alcancem o GameManager por meio de um singleton.

  1. Em GameManager.cs, adicione public static GameManager Instance; e um Awake() com Instance = this;.
  2. Em Meteor.cs, exclua o campo game e chame GameManager.Instance.MeteorLanded() e GameManager.Instance.MeteorCaught() em vez disso.

Pressione “Jogar” e pegue um meteoro: Caught: 1 é exibido, sem erros no Console. Em seguida, pressione “Verificar”.

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;
    }
}

Todas as lições de Criando Jogos de Verdade

Pratique por conta própria: Playground de Unity