Dúvida na aula Construção Extrema

Olá, estou na aula 18 ( Controladores Mobile part II ) Do módulo construção extrema. Tudo funciona corretamente, porém estou obtendo um erro que ainda não entendo por que ocorre, toda vez que solto o cubo.

NullReferenceException: Object reference not set to an instance of an object
GeradorDeCubos.SoltarCubo () (at Assets/Scripts/GeradorDeCubos.cs:62)

NullReferenceException while executing ‘performed’ callbacks of ‘Player/SoltarCubo[/Keyboard/space,/Gamepad/buttonSouth]’

E este é meu código:

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;

public class GeradorDeCubos : MonoBehaviour
{
    
    [SerializeField] private GameObject cuboPrefab; // Referência ao prefab gerado
    [SerializeField] private GameObject ultimoCuboGerado; // Referência ao último gerado, para fins de controle e spawn.
    private AlturaDaConstrucao alturaDaConstrucao; // Referência ao script AlturaDaConstrução
    private Transform cameraPrincipal; // Referencia camera principal
    [SerializeField] private UnityEvent OnSoltarCubo;
    private Vector3 entradasJogador;
    void Start()
    {
        cameraPrincipal = Camera.main.transform; // Recebe camera principal
        alturaDaConstrucao = GetComponent<AlturaDaConstrucao>(); // Referência ao script AlturaDaConstrução
        GerarCubo();
    }

    void Update()
    {
        // Se o último cubo gerado já tiver recebido null, cancela (ele recebe null quando o soltamos na plataforma)
        if (ultimoCuboGerado == null) return;

        // Captura entradas vertical e horizontal do teclado
        //Vector3 entradasJogador = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

        // Transforma os valores de eixos globais de entradasJogador para eixos locais da câmera 
        Vector3 direcaoCamera = cameraPrincipal.TransformDirection(entradasJogador);

        // Eixo y recebe valor 0 constantemente.
        direcaoCamera.y = 0;

        // Faz com que consigamos mover o último cubo gerado
        ultimoCuboGerado.transform.position += direcaoCamera.normalized * Time.deltaTime * 3;
        
    }   

    private void GerarCubo()
    {
        // O último cubo gerado é a própria instância do cuboPrefab, no centro da plataforma, sem rotação e na altura atual, no script AlturaDaConstrução.
        ultimoCuboGerado = Instantiate(cuboPrefab, new Vector3(Random.Range(-3, 4), alturaDaConstrucao.AlturaAtual() + 2, Random.Range(-3, 4)), Quaternion.identity);


        // Valores aleatórios para spawnar o cubo
        int tamanhoX = Random.Range(1, 7);
        int tamanhoY = Random.Range(1, 5);
        int tamanhoZ = Random.Range(1, 7);

        // O último cubo gerado recebe um tamanho aleatório, no caso (localScale) baseado nas variáveis acima
        ultimoCuboGerado.transform.localScale = new Vector3(tamanhoX, tamanhoY, tamanhoZ);

        // O último cubo gerado recebe uma cor aleatória
        ultimoCuboGerado.GetComponent<MeshRenderer>().material.color = Random.ColorHSV();
    }

    public void SoltarCubo()
    {
        // Aqui ativamos a gravidade, ou seja, soltamos o cubo, e então definimos ele como nulo, para que não possamos mais controla-lo
        // no método update
        ultimoCuboGerado.GetComponent<Rigidbody>().useGravity = true;
        ultimoCuboGerado.transform.GetChild(0).gameObject.SetActive(false);
        ultimoCuboGerado = null;
        OnSoltarCubo.Invoke();
        Invoke(nameof(GerarCubo), 2);

    }
    public void MoverCubo(InputAction.CallbackContext value)
    {
        Vector2 input = value.ReadValue<Vector2>();
        entradasJogador = new Vector3(input.x, 0, input.y);
    }
    public void SoltarCubo(InputAction.CallbackContext value)
    {
        if (value.started)
        {
            SoltarCubo();
        }
    }
}

Confere esses pontos abaixo:

1) Componente de Player Input, no objeto GameManager

Verifique se o evento de SolvarCubo está configurado corretamente.

image

2) Arquivo de InputActions no Projeto

Verifique também se está configurado corretamente.

3) Script de GeradorDeCubos

Verique se as variáveis do Inspetor estão defidamente configuradas.

Screenshot_1



Obs: versão da unity: Unity 6 LTS

Em que momento esse erro aparece? Ao iniciar a cena ou quando você aperta o botão de soltar o cubo?

Assim que solto o cubo, pressionando espaço, ou o botão do joystick. Já tentei reiniciar a unity pra ver se era algum bug, mas não corrigiu.

Dá dois cliques em cima do erro no console, vai abrir o local do erro no código. Manda um print.

Os erros acontecem em sequencia. uma parte deles quando eu aperto pra soltar o cubo, e outra parte quando ele encosta na plataforma. O primeiro erro acontece na seguinte linha: 62.

O segundo parece ser em um script do próprio InputSystem:

Mesmo que eu solte apenas um cubo, os dois erros ocorrem duas vezes seguidas, como se eu tivesse tentando instanciar dois cubos. Parece ser algum tipo de “conflito” mas não consigo imaginar o que seja.

Uma coisa que gostaria de destacar, é que estou usando a “VirtualCamera” da cinemachine, e ela consta como depreciada na Unity6, pois queria seguir de maneira mais fiel à aula, e de maneira que eu pudesse acompanhar, mas não parece estar relacionado com o erro. De toda forma, acho que se isso não for interferir no funcionamento do projeto, tudo bem. Só gostaria de saber por que eles acontecem. Poderia ter relação com ter duas teclas para acionar a mesma coisa? como o space e joystick?

Você consegue fazer upload desse projeto no drive? Para eu ter acesso?
Com isso consigo ver com mais detalhes a origem desse erro.

Descobri o erro. Veja só, temos dois método aqui, com mesmo nome (SoltarCubo), porém parametros diferentes:

E no PlayerInput aparece os dois métodos, veja só:

Você escolheu o método sem parametros para tocar quando acontecer a ação de SoltarCubo, mas deve ser o método Dynamic, o do topo.

Eu poderia ter feito toda a lógica em um único método, para evitar esse tipo de situação, porém durante as gravações nem notei isso. Mas enfim, apenas alterar essa configuração já vai resolver.

Oi Lucas, entendi! Testei aqui e deu certo agr, muito obrigado pela ajuda! Você até menciona na aula que não tem problema os dois terem o mesmo nome, por que tem assinaturas diferentes, foi falta de atenção minha mesmo. Valeu!

1 curtida