“O objeto que você deseja instanciar é nulo”. Mas funciona, posso ignorar o erro?

18

Isso nunca aconteceu comigo, então estou um pouco confuso.

GameObject someObject = Instantiate (Resources.Load ("Prefabs/Items/" + someName)) as GameObject;

Isso gera um erro, mas o objeto é realmente instanciado e tudo funciona como pretendido. O erro não interrompe o programa, não importa quantas vezes eu o reproduza.

Posso ignorar esse erro ou há algum problema que não estou vendo?

user4676310
fonte
32
você nunca deve ignorar erros. Eles estão sempre lá por uma razão;)
Gabriele Vierti
5
Quero secundar a ideia de nunca ignorar erros apenas porque "funciona". Por definição, se houver um erro, ele não funcionará. Claro, pode parecer fazer tudo o que você quer, mas isso significa que você ainda não encontrou o que está quebrado.
Fund Monica's Lawsuit

Respostas:

46

Se o objeto for instanciado corretamente, apesar da Intantiate()linha lançar uma exceção, o erro será proveniente de outra instância do script - você pode acidentalmente ter uma segunda cópia em sua cena.

Uma instância está configurada corretamente e executando o Instantiate()conforme o esperado, sem erros, para que o objeto seja criado conforme desejado.

Outra instância está configurada incorretamente e gera um erro. Mas se você estiver apenas olhando para a instância configurada corretamente, esse erro parecerá vir do nada e não terá conseqüências visíveis.

Você pode imprimir o caminho para o objeto em Iniciar - ou em uma verificação nula antes da linha incorreta - para ajudar a rastrear duplicatas indesejadas da cena.

Você absolutamente não deve ignorar esse erro.

Na melhor das hipóteses, está queimando ciclos de computação desnecessariamente. Na pior das hipóteses, é um sinal de que seu jogo está fazendo algo que você não entende completamente, e que pode ser a raiz de problemas muito maiores no futuro.

DMGregory
fonte
12
+1, erros não são os mesmos que avisos, se houver um erro, você nunca saberá quando será escalado para o jogo inteiro travar.
TomTsagk #
13
Nem sempre é seguro ignorar avisos. Mesmo que não seja um erro, ele ainda pode levar a uma situação em que o jogo trava.
Sean Burton
2
Concordo com @SeanBurton, ignorar avisos não é uma prática segura. Você deve ignorar um aviso se, e somente se, entender o que está causando isso e sentir-se confortável de que não está causando um problema no seu código. Mesmo assim, pergunte a si mesmo se você não poderia estar fazendo melhor.
Jack Aidley
3
Todo projeto em que trabalhei com uma grande equipe, em algum momento, ficou tão sobrecarregado com avisos "ignoráveis" que começou a mascarar problemas genuínos. Definitivamente, eu recomendaria tratar os avisos com seriedade também e, se for inevitável, desabilitá-lo para a linha relevante, juntamente com um comentário que defina claramente por que é seguro ignorar a geração do aviso.
DMGregory
11
Estou 100% com o @DMGregory, só trabalhei em equipes muito pequenas, mas o par de vezes em que os avisos começaram a empilhar era horrível encontrar problemas "genuínos", ou você os sentia falta o tempo todo. Meu MO é manter o log limpo, exceto para testes, mesmo que eu tenha que desativar os avisos no código dos plug-ins (por favor, nunca faça plug-ins com avisos NUNCA), é muito melhor no IMO a longo prazo. Editar: para ficar claro, nunca desative os avisos, a menos que você tenha 100% de certeza de que não há outro caminho (o que acontece 0,001% do tempo), sempre os corrija.
Trisibo 1/11
21

Responda

Deixe-me começar por responder sua pergunta diretamente:

funciona, posso ignorar o erro?

Você poderia . Você não deveria , porque significa que algo está errado. Você se acostumaria com esse erro, mas ele poderia "ocultar" ou causar outro erro.

Atualmente você tem uma mensagem de erro e ainda funciona corretamente. Por outro lado, ele não funciona e não tem (ou melhor: não reconhece) feedback por que, é muito pior!

Adendo

Para descobrir de onde isso vem, divida tudo isso em várias linhas.

string resourceLocation = "Prefabs/Items/" + someName;
Object prefab = Resources.Load(resourceLocation);
Object instance = Instantiate(prefab);
GameObject someObject = instance as GameObject;

Um erro informa apenas em que linha aconteceu. Se o erro ocorrer neste código, o número da linha informará mais sobre qual parte deu errado aqui. Além disso, aconselho o uso da versão genérica de Resources.Load, que na verdade nos daria um passo a menos para nos preocuparmos:

string resourceLocation = "Prefabs/Items/" + someName;
GameObject prefab = Resources.Load<GameObject>(resourceLocation);
GameObject someObject = Instantiate(prefab);

Descobrir o porquê

  • Agora, um pouco da experiência do Unity nos diz que "O objeto que você deseja instanciar é nulo" é causado por Instantiate().
  • Então, isso significa que prefabé null.
  • Então isso significa Resources.Loadretornos null.
  • A documentaçãoResources.Load diz " Retorna o ativo em pathse ele puder ser encontrado; caso contrário, retorna nulo " .
  • Então isso significa que ele não encontra o caminho especificado (a string que eu chamei resourceLocation)

Algo está errado com esse caminho; portanto, o primeiro passo óbvio seria ver o que realmente acaba sendo, com o Debug.Log. Como "tudo funciona como pretendido", é provável que exista alguma duplicação em que uma versão funcione e a outra dê esse erro.

Nesse caso, é uma boa ideia usar a versão de 2 parâmetros do Debug.Log Debug.Log(resourceLocation, gameObject);. Agora, se você clicar na mensagem de log no editor do Unity, ele selecionará de GameObjectonde veio.

Raphael Schmitz
fonte