[RESOLVIDO] Unity - SceneManager.LoadScene abre scene com objeto "vazio"

Boa tarde! Pessoal, seguinte

Quando o jogador inicia o jogo e vai até a scene principal do jogo, as coisas funcionam, daí se eu clicar na seta de voltar pra abandonar o jogo e voltar pra scene Inicia, ele volta normal, mas se for pro jogo novamente as coisas não funcionam normal como deveriam funcionar. Nessa situação, quando lanço o dado, ele não conclui a ação e dá esse erro

MissingReferenceException: The object of type ‘Personagem’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
Ludo3DPowers.tratamentoRoboEquipeNaoPodemSeDeslocar (System.Int32 valorDado) (at Assets/SCRIPTS/[Ludo3DPowers_e_Poderes]/Ludo3DPowers/Ludo3DPowers.cs:2332)
Ludo3DPowers.recebeValorDoDado3D (System.Int32 numSorteado) (at Assets/SCRIPTS/[Ludo3DPowers_e_Poderes]/Ludo3DPowers/Ludo3DPowers.cs:956)
Dado3D+d__57.MoveNext () (at Assets/SCRIPTS/Dado3D_ItemDadoNoCanvas/Dado3D.cs:289)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <685c48cf8f0b48abb797275c046dda6a>:0

A origem do erro está em “Dado3D.cs:289”

Não entendo, não faz sentido esse erro, pois o processo de mudança de scene é o mesmo. A mesma coisa acontece se o jogador concluir o jogo e ir pra scene da vitória. Se o Jogador Voltar pra scene principal do jogo, acontece o mesmo erro

Alguém sabe o que está acontecendo, se é alguma coisa que falta configurar na Unity quando se troca de scene? Obg!

Pessoal, alguém me ajuda pfv, ainda não consegui resolver essa bronca

Gente, ajuda aí pfv! Obg!

Bom dia @wlcs22, não entendo absolutamente nada de Unity, mas aparenta ser mais um problema de lógica mesmo.

o problema diz:

Olhando um pouco a documentação do Unity, consegui achar algo que talvez te ajude.

basicamente diz ai que ao trocar de cena, tudo é destruído da cena atual, porém ao chamar DontDestroyOnLoad(seu objeto);
Você irá conseguir preservar seu objeto Personagem.

Ou, a outra forma que é recomenda pelo erro que te deu, é verificar se o cara é null antes de tentar fazer alguma ação, tipo:

if (objeto != null) {
    // Faça operações no objeto
} else {
    // Faça tratativas sobre o objeto que foi destruído
}

espero que de certo, abraço.

Thiago, obg pela respsta!

Sim, quando muda de scene tudo da scene anterior é destruído. Não é pra colocar “DontDestroyOnLoad” em Personagem por que ele só deve existir na scene do Jogo.

Já testei. Chequei o objeto que está dando erro. Daí ele dá erro novamente com outro objeto, e outro, e outro… A questão é a seguinte, se abrir a scene do jogo de primeira não dá erro nenhum, então por que ele tá dando esse erro quando saio e volto pra ela novamente? É isso que não estou conseguindo entender. Os Scripts de mudança de scene são os mesmos. Teoricamente, ele ao sair da scene do jogo, a scene do jogo é destruída e, quando o jogador volta pra scene do jogo novamente, a scene atual que o jogador está é destruída e a do jogo é aberta do zero, não é pra dar esse erro de jeito nenhum! Já tem um tempo que não consigo resolver essa.

Pessoal, rodei até chegar no erro de fato. Tenho um Invoke() dentro de uma Coroutine. Esse Invoke() está assim:

private IEnumerator aguardarResultado() {
      while(!_rigidbody.IsSleeping()) {
            yield return null;
      }

      int numSorteado = 1;
      numSorteado = Vector3.Dot(Vector3.up, -transform.up) > 0.6f ? 6 : numSorteado;
      numSorteado = Vector3.Dot(Vector3.up, transform.forward) > 0.6f ? 3 : numSorteado;
      numSorteado = Vector3.Dot(Vector3.up, -transform.forward) > 0.6f ? 4 : numSorteado;
      numSorteado = Vector3.Dot(Vector3.up, transform.right) > 0.6f ? 5 : numSorteado;
      numSorteado = Vector3.Dot(Vector3.up, -transform.right) > 0.6f ? 2 : numSorteado;

      OnNumSorteado?.Invoke(numSorteado);

      horizontalLayoutGroup.enabled = true;
      transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
}

OnNumSorteado” é um Evento public static event System.Action OnNumSorteado; declarado nos atributos do Script Dado3D.

O erro está acontecendo na linha OnNumSorteado?.Invoke(numSorteado);

Quando abro a scene do jogo pela 1ª vez, ele roda sem problemas. Mas quando abro ela da 2ª vez em diante, dá erro. O que está depois dessa linha OnNumSorteado?.Invoke(numSorteado); não é executado. O Erro é esse:

MissingReferenceException: The object of type ‘Image’ has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
Ludo3DPowers.recebeValorDoDado3D (System.Int32 numSorteado) (at Assets/SCRIPTS/[Ludo3DPowers_e_Poderes]/Ludo3DPowers/Ludo3DPowers.cs:890)
Dado3D+d__58.MoveNext () (at Assets/SCRIPTS/Dado3D_ItemDadoNoCanvas/Dado3D.cs:295)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <685c48cf8f0b48abb797275c046dda6a>:0)

O problema não é no “MissingReferenceException” com o ‘Image’. Ele é consequência do fato de o Invoke() não ter sido realizado sem erro no Script Dado3D quando a scene é aberta pela 2ª vez.

Uma das coisas que vi nas pesquisas é que o jogo poderia estar pausado. Não é, pois nem implementei isso. Infelizmente ainda não achei nada nas pesquisas sobre esse erro. Alguém me ajuda pfv! Desde já mt obg!

RESOLVIDO!

@Thiago_Machadook, tá vendo que o buraco era mais embaixo?! Pois bem.
public static event System.Action<int> OnNumSorteado; é uma STATIC. Ela não sofria alteração quando mudava de scene. Daí eu solicitava ela e ela por não ter sido recriada ou reiniciada no LoadScene dava esse erro. Daí nas Pesquisas encontrei esse Tópico, no Comentário feito por “3 respostas” tive a resposta.

No Script do Jogo tenho o Método “recebeValorDoDado3D(int numSorteado)” que está no Awake() e recebe de Dado3D na Linha “Dado3D.OnNumSorteado += recebeValorDoDado3D;” o Valor do Dado que foi Sorteado.

A Solução foi inserir a linha “Dado3D.OnNumSorteado -= recebeValorDoDado3D;” no Método “recebeValorDoDado3D(int numSorteado)” depois do Valor do Dado ser tratado! Também inseri nos Métodos “vitoriaDoHumano()” e “vitoriaDoRobo()” para testes, mas apesar disso, deixei neles também.

Fica aí o Tópico pra quem precisar.
Quem diria, o LoadScene não destrói a Scene por completo, ela deixa as variáveis estáticas dessa forma, pense… Graças a Deus consegui resolver essa bronca. Obg pela atenção!

1 curtida