Menu
CoddyTech

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.

challenge icon

Desafio

Fácil

Chuva 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ático Instance do tipo GameManager e defina-o como este script em Awake.
  • Em Meteor.cs, exclua o campo game e reporte por meio de GameManager.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;
    }
}
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 Criando jogos de verdade