前提・実現したいこと
Unity2018.2.20f1にて3Dのゲームを制作しています。
UIをクリックした際にUI管理オブジェクトが持っているUIcontoller.cs内の関数が呼ばれ、その関数でPlayerController内のフラグ切り替え処理が呼ばれるという部分を実装したいと思っています。
発生している問題・エラーメッセージ
上記箇所でエディタ上でのゲームの実行からの終了時にエラー文が出ます。
動作自体は意図した動作を実現できていますが、エラー文の原因を知りたいと思い質問させて頂きました。
NullReferenceException: Object reference not set to an instance of an object UIcontroller.AutoShot () (at Assets/Scripts/UIcontroller.cs:314) UnityEngine.Events.InvokableCall.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:166) UnityEngine.Events.UnityEvent`1[System.Boolean].Invoke (Boolean arg0) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_1.cs:63) UnityEngine.UI.Toggle.Rebuild (CanvasUpdate executing) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Toggle.cs:85) UnityEngine.UI.CanvasUpdateRegistry.PerformUpdate () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/CanvasUpdateRegistry.cs:123) UnityEngine.Canvas:SendWillRenderCanvases()
該当のソースコード
UIcontroller.cs
C#
1void Start() { 2 //プレイヤーの取得処理 3 player = GameObject.Find("Player"); 4 //プレイヤーのスクリプトの取得処理 5 playerController = player.GetComponent<PlayerController>(); 6} 7 8 //オート射撃モードを切り替える関数 9 public void AutoShot() 10 { 11 12 //オートモードが実行中でない場合 13 if (isSelecting == false) 14 { 15 //playerContoroller内のオート射撃切り替え処理を実行 16 playerController.setAutoShot(); //←314行目 17 //切り替えフラグをonにして1回しか起動されないように 18 isSelecting = true; 19 } 20 21 22 //切り替えフラグを切る処理を予約 23 StartCoroutine(resetAutoShotFlag()); 24 25 } 26 27 //切り替えフラグをオフにする処理 28 private IEnumerator resetAutoShotFlag() 29 { 30 yield return new WaitForSeconds(0.2f); 31 isSelecting = false; 32 33 }
playerController.cs側の該当部分
既に持っているisAutoShotというフラグを切り替える関数
C#
1 //自動射撃のオンオフを切り替える処理 2 public void setAutoShot() 3 { 4 //オートモードが実行中でない場合 5 if (isAutoShot == false) 6 { 7 isAutoShot = true; 8 } 9 //オートモードが実行中の場合 10 else if (isAutoShot == true) 11 { 12 isAutoShot = false; 13 } 14 }
試したこと
NullReferenceExceptionということでplayerControllerへの参照部分に何か問題があるのかと思い、以下のようにコードを書き替えた場合、エラーが出なくなりました。
C#
1playerController.setAutoShot(); 2↓ 3GameObject.Find("Player").GetComponent<PlayerController>().setAutoShot();
事前にグローバル変数でクラスを定義して、StartでGetComponentを行い参照を繋いでおけばその後は再度参照せずにアクセスできると考えていたのですが、違うのでしょうか?
また、通常のNullReferenceExceptionと違い実行中ではなく実行終了時、エディタに戻った際にエラーが出るのは何故なのでしょうか?
初歩的な疑問で大変申し訳ないのですが、ご教授頂ければ幸いです。
######追記
ご指摘を受けまして、以下のようにエラー行の直前にデバッグログを追記し参照が切れていないかを確認したところ参照先が表示されました。
(これはエラー時のログではなく正常動作時のログです。(ゲームの実行終了時に発生する)エラー時はエラーの内容のみが表示され、直前のdebug.logは実行されていないようで何も表示されません。)
C#
1Debug.Log(”Player: ” + player + "Player Controller: " + playerController);を入れて実行したところ、 2playerController.setAutoShot();
Player: Player (UnityEngine.GameObject)Player Controller: Player (PlayerControllerScript.PlayerController)
回答1件
あなたの回答
tips
プレビュー