"Das Objekt, das Sie instanziieren möchten, ist null." Aber es funktioniert. Kann ich den Fehler ignorieren?

18

Das ist mir noch nie passiert, deshalb bin ich ein bisschen verwirrt.

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

Dies löst einen Fehler aus, aber das Objekt wird tatsächlich instanziiert und alles funktioniert wie beabsichtigt. Der Fehler stoppt das Programm nicht, egal wie oft ich das reproduziere.

Kann ich diesen Fehler ignorieren oder gibt es ein Problem, das ich nicht sehe?

user4676310
quelle
32
Sie sollten niemals Fehler ignorieren. Sie sind immer für einen Grund da;)
Gabriele Vierti
5
Ich möchte die Idee unterstützen, Fehler niemals zu ignorieren, nur weil "es funktioniert". Per Definition funktioniert es nicht, wenn ein Fehler auftritt. Sicher, es scheint alles zu tun, was Sie wollen, aber das bedeutet nur, dass Sie das kaputte Stück noch nicht gefunden haben.
Fund Monicas Klage

Antworten:

46

Wenn das Objekt korrekt instanziiert wird, obwohl die Intantiate()Zeile eine Ausnahme auslöst, kommt der Fehler von einer anderen Instanz des Skripts. Möglicherweise befindet sich versehentlich eine zweite Kopie in Ihrer Szene.

Eine Instanz ist ordnungsgemäß konfiguriert und führt die Instantiate()erwartungsgemäße Ausführung ohne Fehler aus, sodass das Objekt wie gewünscht erstellt wird.

Eine andere Instanz ist falsch konfiguriert und löst einen Fehler aus. Wenn Sie sich jedoch nur die korrekt konfigurierte Instanz ansehen, scheint dieser Fehler von ungefähr zu kommen und hat keine sichtbare Konsequenz.

Sie können den Pfad zum Objekt beim Start oder bei einer Nullprüfung direkt vor der betreffenden Zeile ausdrucken, um unerwünschte Szenen-Duplikate aufzuspüren.

Sie sollten diesen Fehler auf keinen Fall ignorieren.

Bestenfalls werden unnötig Rechenzyklen gebrannt. Im schlimmsten Fall ist dies ein Zeichen dafür, dass Ihr Spiel etwas tut, das Sie nicht vollständig verstehen, und dass dies die Ursache für weitaus größere Probleme auf der ganzen Linie sein kann.

DMGregory
quelle
12
+1, Fehler sind nicht dasselbe wie Warnungen. Wenn ein Fehler auftritt, wissen Sie nie, wann er zum Absturz des gesamten Spiels führen wird.
TomTsagk
13
Es ist auch nicht immer sicher, Warnungen zu ignorieren. Auch wenn es sich nicht um einen Fehler handelt, kann dies möglicherweise zu einem Absturz des Spiels führen.
Sean Burton
2
Ich stimme @SeanBurton zu, das Ignorieren von Warnungen ist keine sichere Praxis. Sie sollten eine Warnung nur dann ignorieren, wenn Sie verstehen, was sie verursacht, und sich sicher sind, dass sie kein Problem in Ihrem Code verursacht. Selbst dann frag dich, ob du es nicht besser machen könntest.
Jack Aidley
3
Jedes Projekt, an dem ich mit einem großen Team gearbeitet habe, war irgendwann so überladen mit "ignorierbaren" Warnungen, dass es anfing, echte Probleme zu verschleiern. Ich würde also auf jeden Fall empfehlen, Warnungen auch ernst zu nehmen, und wenn dies unvermeidlich ist, deaktivieren Sie sie für die entsprechende Zeile zusammen mit einem Kommentar, der klar definiert, warum es sicher ist, die Erzeugung der Warnung dort zu überspringen.
DMGregory
1
Ich bin zu 100% bei @DMGregory, ich habe nur in sehr kleinen Teams gearbeitet, aber die paar Mal, wenn Warnungen aufgetaucht sind, war es schrecklich, "echte" Probleme zu finden, oder Sie würden sie die ganze Zeit vermissen. Mein MO ist es, das Protokoll sauber zu halten, außer zum Testen, auch wenn ich Warnungen im Code der Plugins deaktivieren muss (bitte mache KEINE Plugins mit Warnungen), es ist auf lange Sicht viel besser, IMO. Bearbeiten: Deaktivieren Sie zur Klarheit niemals Warnungen, es sei denn, Sie sind sich zu 100% sicher, dass es keine andere Möglichkeit gibt (was in 0,001% der Fälle der Fall ist). Korrigieren Sie sie immer tatsächlich.
Trisibo
21

Antworten

Lassen Sie mich zunächst Ihre Frage direkt beantworten:

es funktioniert, kann ich den Fehler ignorieren?

Sie könnten . Sie sollten nicht, weil es bedeutet, dass etwas schief geht. Sie würden sich an diesen Fehler gewöhnen, aber er könnte sich "verstecken" oder einen anderen Fehler verursachen.

Derzeit haben Sie eine Fehlermeldung und es funktioniert immer noch richtig. Umgekehrt ist es weitaus schlimmer, wenn es nicht funktioniert und kein Feedback hat (oder besser gesagt: es nicht erkennt), warum!

Rat

Um herauszufinden, woher das kommt, teilen Sie das Ganze in mehrere Zeilen auf.

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

Ein Fehler gibt nur an, in welcher Zeile er aufgetreten ist. Wenn der Fehler in diesem Code auftritt, erfahren Sie anhand der Zeilennummer, welcher Teil hier falsch lief. Außerdem würde ich raten, die generische Version von zu verwenden Resources.Load, die uns tatsächlich einen Schritt weniger Zeit lässt, uns Sorgen zu machen:

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

Finden Sie heraus, warum

  • Ein wenig Erfahrung mit Unity zeigt uns, dass das Objekt, das Sie instanziieren möchten, null ist Instantiate().
  • Das heißt prefabalso null.
  • Das heißt also Resources.LoadRendite null.
  • In der Dokumentation zuResources.Load " Gibt das Asset zurück, pathwenn es gefunden wird, andernfalls wird null zurückgegeben. "
  • Das bedeutet, dass der angegebene Pfad (der von mir aufgerufene String resourceLocation) nicht gefunden wird.

Irgendetwas stimmt mit diesem Pfad nicht. Der naheliegende erste Schritt wäre also, mit Debug.Log zu sehen, wie es tatsächlich ausgeht. Da "alles wie beabsichtigt funktioniert", ist es wahrscheinlich, dass eine Verdoppelung stattfindet, bei der eine Version funktioniert, und die andere gibt Ihnen diesen Fehler.

In diesem Fall ist es ratsam, die 2-Parameter-Version von Debug.Log zu verwenden Debug.Log(resourceLocation, gameObject);. Wenn Sie nun im Unity-Editor auf die Protokollnachricht klicken, wird der Ursprung ausgewählt GameObject.

Raphael Schmitz
quelle