Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Dúvida] Outra maneira de fazer

Olá!! Eu fiz os códigos do seguinte jeito:

GameManager

using UnityEngine;

public class GameManager
{
    private GameManager()
    {
        inputManager = new InputManager();
    }

    private static GameManager instance = null;

    public InputManager inputManager;

    public static GameManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new GameManager();
            }

            return instance;
        }
    }

}

PlayerBehavior

using UnityEngine;

public class PlayerBehavior : MonoBehaviour
{

    [SerializeField] private float moveSpeed = 10f;

    void Update()
    {
        float moveDirection = GameManager.Instance.inputManager.Movement * Time.deltaTime * moveSpeed;
        transform.Translate(moveDirection, 0, 0);
    }
}

No final, o jogo está funcionando do msm jeito, porém, gostaria de saber se tem alguma diferença significativa desse código e do feito em aula.

Eu acredito que no meu código possa ter um problema relacionado a inicialização do GameManager, pois ele está sendo inicializado primeiramente dentro do Update do Player Behavior, e isso seria ruim pois ele dependeria do player estar na cena para ser inicializado, e consequentemente não funcionaria em menus e etc... estou certo?

1 resposta
solução!

Olá Cauê! Tudo bem?

Você está absolutamente certo em sua observação sobre a inicialização do GameManager.

No seu código, o GameManager é instanciado dentro do Update do PlayerBehavior, o que significa que ele só será inicializado quando o PlayerBehavior for executado. Isso pode ser problemático em situações onde o GameManager precisa ser acessado antes do PlayerBehavior, como em menus ou outros elementos do jogo que não dependem do jogador.

A abordagem sugerida na aula, que utiliza o método Awake() no GameManager, é uma prática comum para garantir que o GameManager seja inicializado antes de qualquer outro componente que dependa dele. Isso é feito porque o Awake() é chamado antes do primeiro Start(), garantindo que todas as inicializações necessárias sejam feitas antes que o jogo comece a rodar.

Além disso, a implementação do padrão Singleton no GameManager garante que haja apenas uma instância dessa classe durante toda a execução do jogo, evitando problemas de múltiplas instâncias que poderiam causar comportamentos inesperados.

Aqui está um exemplo de como o seu GameManager poderia ser estruturado seguindo a abordagem da aula:

using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance { get; private set; }
    public InputManager InputManager { get; private set; }

    private void Awake()
    {
        if (Instance != null)
        {
            Destroy(this.gameObject);
            return;
        }
        
        Instance = this;
        DontDestroyOnLoad(this.gameObject);
        InputManager = new InputManager();
    }
}

E no PlayerBehavior, você acessaria o InputManager assim:

using UnityEngine;

public class PlayerBehavior : MonoBehaviour
{
    [SerializeField] private float moveSpeed = 10f;

    void Update()
    {
        float moveDirection = GameManager.Instance.InputManager.Movement * Time.deltaTime * moveSpeed;
        transform.Translate(moveDirection, 0, 0);
    }
}

Essa abordagem garante que o GameManager seja inicializado corretamente e esteja disponível para qualquer script que precise dele, independentemente de o jogador estar na cena ou não.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.