「インスタンス化するオブジェクトはnullです」しかし、動作します。エラーを無視できますか?


18

これは私には一度も起こったことがないので、少し混乱しています。

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

これによりエラーがスローされますが、オブジェクトは実際にインスタンス化され、すべてが意図したとおりに機能します。このエラーを何度再現しても、プログラムは停止しません。

このエラーを無視できますか、または表示されない問題がありますか?


32
エラーを無視しないでください。彼らは常に理由があります;)
ガブリエレビエルティ

5
「機能する」という理由だけでエラーを無視しないという考えを二番目にしたいと思います。定義により、エラーがある場合は機能しません。確かに、それはあなたがそれを望むすべてをするように見えるかもしれませんが、それはあなたがまだ壊れたビットをまだ見つけていないことを意味します。
ファンドモニカの訴訟

回答:


46

Intantiate()行が例外をスローしてもオブジェクトが正しくインスタンス化される場合、エラーはスクリプトの別のインスタンスから発生しています。誤ってシーンに2つ目のコピーがある可能性があります。

1つのインスタンスが正しく構成Instantiate()され、エラーなしで期待どおりに実行されるため、オブジェクトは必要に応じて作成されます。

別のインスタンスが正しく構成されておらず、エラーがスローされます。ただし、正しく構成されたインスタンスを表示しているだけの場合、このエラーはどこからも発生していないようで、目に見える結果はありません。

不要なシーンの重複を追跡するのに役立つように、開始時または問題のある行の直前のヌルチェックでオブジェクトへのパスを印刷できます。

このエラーを絶対に無視しないでください。

せいぜい、それは不必要に計算サイクルを燃やしています。最悪の場合、それはあなたのゲームがあなたが完全に理解していないことをしているという兆候であり、それは将来のはるかに大きな問題の根源となり得る。


12
+1、エラーは警告と同じではありません。エラーが発生した場合、ゲームがクラッシュするまでエスカレートするタイミングはわかりません。
-TomTsagk

13
警告を無視することも常に安全ではありません。エラーでなくても、ゲームがクラッシュする可能性があります。
ショーンバートン

2
@SeanBurtonに同意します。警告を無視することは安全な方法ではありません。警告の原因を理解し、コードで問題を引き起こしていないことがわかっている場合にのみ、警告を無視する必要があります。それでも、もっと上手くできなかったら自分に問いかけてください。
ジャックエイドリー

3
私が大規模なチームで取り組んできたすべてのプロジェクトは、ある時点で「無視できる」警告で過負荷になり、本物の問題を隠し始めました。だから私は間違いなく警告を真剣に扱うことを主張し、もしやむを得ない場合は、関連する行で警告を無効にし、そこに警告を生成するのが安全である理由を明確に説明するコメントを付けます。
DMGregory

1
私は@DMGregoryに100%関わっています。非常に小さなチームでしか仕事をしていませんが、警告が山積みになり始めた2回は「本物の」問題を見つけるのは恐ろしいことでした。私のMOは、テストを除いてログをきれいに保つことです。たとえプラグインのコードの警告を無効にしなければならない場合でも(警告のあるプラグインを作成しないでください)、長期のIMOでははるかに優れています。編集:明確にするために、他の方法がないことを100%確信していない限り(常に0.001%発生します)、常に実際に修正するまで、警告を無効にしないでください。
トリシボ

21

回答

あなたの質問に直接答えることから始めましょう:

動作しますが、エラーを無視できますか?

あなたはできました。何かがうまくいかないことを意味するので、そうすべきではありません。このエラーに慣れるでしょうが、別のエラーを「隠す」か、引き起こす可能性があります。

現在、エラーメッセージが表示されますが、引き続き正常に機能します。反対に、機能せ、フィードバックを持たない(または認識しない)理由は、はるかに悪いです!

助言

これがどこから来たのかを知るには、この全体をいくつかの行に分割します。

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

エラーは、どの行で発生したかを示すだけです。このコードでエラーが発生した場合、行番号はここでどの部分が間違っていたかについての詳細を示します。また、の汎用バージョンを使用することをお勧めします。これによりResources.Load、実際に心配する必要が1つ少なくなります。

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

理由を見つける

  • さて、Unityの経験から、「インスタンス化したいオブジェクトがnullである」の原因はであることがわかりますInstantiate()
  • つまり、ということprefabですnull
  • したがって、それはをResources.Load返しますnull
  • ドキュメントにResources.Loadは、「アセットpathが見つかった場合にアセットを返します。見つからない場合はnullを返します。
  • つまり、指定されたパス(私が呼び出した文字列resourceLocation)が見つからないことを意味します

このパスに問題があるため、最初のステップは、Debug.Logを使用して、実際に何が実際に行われるかを確認することです。「すべてが意図したとおりに動作する」ため、1つのバージョンが動作し、他のバージョンがこのエラーを発生させる場所で重複が発生している可能性があります。

その場合、Debug.Logの2パラメーターバージョンを使用することをお勧めしますDebug.Log(resourceLocation, gameObject);。Unityエディターでログメッセージをクリックすると、メッセージの送信元が選択さGameObjectれます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.