質問: 0; } if (BoxHP <= 0) { //Debug.Log("破壊"); adse.Play(); itemMng.makeItems(itemMakeNum, transform.position); //【Line55】 Destroy(gameObject); } } ``` ### 試したこと 「NullReferenceException」はよくあるnull参照エラーですから、ItemManagerクラスのtargetItem.GetGameObject()が何も示せていない事を疑いました。 同クラスのUpdate()に`Debug.Log("デバッグ : " + targetItem.GetGameObject().name);`を記入したところ、オブジェクトの名前が返ってきました。しかし、同クラスのmakeItems()に上記のデバッグ文を挿入したところ、表題のようなエラーが発生しました。 makeItems()メソッド内で空参照エラーが発生する理由が思い当たりません。 デバッグ用に比較文を(true)にしてある【Line68】を本来の式に戻し、「確立で特別なアイテムを生成する」という処理にした上で問題のブロックが実行されなかった場合......「通常アイテムをn個生成」とコメントされた箇所の処理、Instantiate()は正常に動作しました。 また、Box.cs内で宝箱破壊時に効果音を再生`adse.Play();`しているのですが、今回のエラー発生時、`Destroy(gameObject);`されずに残っているのかSEが無限再生されるように暴走します。 特別なアイテムを生成しない、通常アイテムを生成する時はSEやDestroyに異常は感じられませんでした。 ### デバッグ状況1(追記) `targetItem.GetGameObject()`の補足をしますと、targetItemはItem型の変数でアイテムの各種情報(名前や属性,説明,GameObjectなど)をprivate typeで格納しています。この中にGameObjectがあり、`GetGameObject()`で取得できるようになっています。 ここで、Item型のGetGameObjectは他の場所でも頻繁に利用していて問題が起きていないために見落としていましたが、問題の箇所で`targetItem`のみで確認してみたところヌルリファレンスエラーは発生しませんでした。 問題のメソッド内で.GetGameObject()を須いたときのみエラーが発生するらしいことまでが分かりました。 しかし、「targetItemの中身はどの時点でも空ではない」「GetGameObject()はprivateな変数を返すだけのメソッド」「Item型の実体の方も問題のメソッド以外では参照が確認できる」「Item型の実体の方でGameObjectの参照を格納する変数に変更を加える(代入する)処理は一切書き込んでいない」 となると、余計に分かりません。 何かちょっとしたヒントでもいいので、突破口に成るような何かが見つかるといいのですが...... ### デバッグ状況2(追記) Item型のインスタンスを、ItemManagerクラスのtargetItemに参照を格納し、壊れるとアイテムを出現させるBoxクラスからItemManagerクラスのmakeItems()を実行するとエラーが発生することがわかりました。 ItemクラスのGetGameObject()だけでなく、Itemクラス内の全メソッドにおいて同様のエラーが発生します。 その条件は恐らくですが、「BoxクラスからItemManagerクラスのメソッドを呼び出す。そのメソッドがまたItemクラスのメソッドを呼び出す」といった構造をしていることだと思いましたが、それをどのように解決させるか検討もつきません。 「BoxクラスからItemManagerクラスのメソッドを呼び出す。そのメソッドがItemクラスのインスタンスの参照そのものを表示する」という先よりも一段階少ない工程でデバッグしてみると、ヌルにはなりませんでした。 HSP言語のループのように、C#のメソッドを呼び出す深さ(ネスト)が3つくらいと言った、Unity C#特有の制限があるのでしょうか。 ### 補足情報(FW/ツールのバージョンなど) Unity2018 2.0f2、VS2017、Windows 10 home 64bit。
回答: とてもしょうもない話でした。 アイテム管理ゲームオブジェクトが持つItemManager.csの参照を得るための手順を誤っていただけで、作ったクラスやメソッド等に特段問題は見つかりませんでした。 強いて言えば、Box.cs内でAudioSourceを鳴らす処理がDestroyすることで無駄になっており、PlayClipToPointメソッドに変更する程度の修正点があるのみでした。(今回のエラーと関係なし) 対象のGameObjectの参照を取るべくインスペクタでD&Dし、Start()でGetCompornent()する。 たったこれだけの工程を間違えるのはとても情けない。 これに多くの時間を割いた自分が情けない。 視野が狭すぎます......イベント直前で徹夜気味に弄るものじゃないですね。