質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

コンポーネントの取得でのNullエラーの解消法

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 295

kaboche

score 1

前提・実現したいこと

UnityにてInputFieldを用いて鍵番号で開く金庫のイベントを作成しています。現在Nullエラーが解消できずイベントが作成できないため、Nullエラーの解消法を知りたいです。
InputFieldは他のオブジェクトでも使用するので、表示する部分とイベントの内容を別クラスにしています。

発生している問題・エラーメッセージ

表1で表2のNullエラーが発生しています。上記部分が取得できないだけなら取得方法を変えればよいのですが、同じスクリプトの63行目(表3)は取得できていたのでなぜエラーが出ているかわからず質問させていただきました。

表1

inputFeildController.inputField.onEndEdit.AddListener(data => InputFieldEvent());


表2

NullReferenceException: Object reference not set to an instance of an object
UnderSafeEvent.Start () (at Assets/OriginalGame/Scripts/UnderSafeEvent.cs:33)


表3

var inputText = inputFeildController.inputField.text;

該当のソースコード

関係のありそうなスクリプト全文を下記いたします。

表4

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class UnderSafeEvent : MonoBehaviour
{
    //イベントトリガー
    private EventTrigger eventTrigger;
    private EventTrigger.Entry entry1;

    //テキストを管理するスクリプト
    private TextController[] textControllers;

    //メモ管理用スクリプト
    private MemoController memoController;

    //InputField管理用のスクリプト
    private InputFeildController inputFeildController;

    //鍵番号
    public string keyNum;

    // Start is called before the first frame update
    void Start()
    {
        //InputFieldControllerを取得
        inputFeildController = gameObject.GetComponent<InputFeildController>();

        //InputFieldにイベントを登録
        inputFeildController.inputField.onEndEdit.AddListener(data => InputFieldEvent());

        //テキスト管理のスクリプトを取得
        textControllers = gameObject.GetComponents<TextController>();

        //メモ管理用スクリプトを取得
        memoController = gameObject.GetComponent<MemoController>();
    }

    // Update is called once per frame
    void Update()
    {

    }

    public void ChengeEvent()
    {
        //現在のイベントを非アクティブにする
        gameObject.GetComponent<EventTrigger>().enabled = false;

        //別のイベントを追加する
        eventTrigger = gameObject.AddComponent<EventTrigger>();
        entry1 = new EventTrigger.Entry();
        entry1.eventID = EventTriggerType.PointerClick;
        entry1.callback.AddListener(data => memoController.StartEvent());
        eventTrigger.triggers.Add(entry1);
    }

    public void InputFieldEvent()
    {
        var inputText = inputFeildController.inputField.text;

        if(inputText == "0000")
        {
            Debug.Log("開いたよ");
            inputFeildController.RemoveInputField();
            textControllers[0].ActiveText();
            textControllers[0].UpdateText();
            ChengeEvent();
        }
        else
        {
            Debug.Log("開かないよ");
            inputFeildController.RemoveInputField();
            textControllers[1].ActiveText();
            textControllers[1].UpdateText();
        }
    }
}


表5

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class InputFeildController : MonoBehaviour
{
    //InputField表示用のUI
    private GameObject inputFieldUI;
    //パス入力用のInputField
    public TMP_InputField inputField;

    // Start is called before the first frame update
    void Start()
    {
        //表示用のUIを取得
        inputFieldUI = GameObject.Find("InputFieldUI").transform.Find("InputField").gameObject;
        //InputFieldを取得
        inputField = inputFieldUI.GetComponentInChildren<TMP_InputField>();
    }

    // Update is called once per frame
    void Update()
    {

    }

    public void ActiveInputField()
    {
        //InputFieldを表示する
        inputFieldUI.SetActive(true);
        Time.timeScale = 0;
    }

    public void RemoveInputField()
    {
        //InputFieldを非表示にする
        inputFieldUI.SetActive(false);
        Time.timeScale = 1;
    }
}

試したこと

表1のコードの上に表6と表7を入力して実行したところ表6は取得できていて表7はNullでした。
また、表3の上に表7を入力して実行した場合はコンポーネントを取得できていて、その後の処理も問題なく実行できました。
表5のコンポーネント取得は問題なくされていました。

表6

Debug.log(inputFeildController);


表7

Debug.log(inputFeildController.inputField)

補足情報(FW/ツールのバージョンなど)

Unity2018.4.23f1
VisualStudio2019

不明点や不足の情報があればご連絡ください。
宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

・原因
Nullが発生したり問題無かったりするのは下記の順で処理が行われているせいです。

--ゲーム起動時の処理--
1.UnderSafeEventクラスのStart-inputFieldが代入されてないのでNull
2.InputFeildControllerクラスのStart-inputFieldに値が代入

--ゲーム中の処理--
3.UnderSafeEventクラスのInputFieldEvent-inputFieldが代入されているのでNullにならない

・解決法
二通りあります。

・InputFeildControllerクラスのvoid Start()public void Init()などに書き換えNullが発生する前に呼び出す。
書き換える関数名は一例なのでInitでなくとも何でも良いです。
Nullエラーが発生している直ぐ上に書き込めば解決するかと思います。

inputFeildController.Init();
inputFeildController.inputField.onEndEdit.AddListener(data => InputFieldEvent());

・InputFeildControllerクラスのpublic TMP_InputField inputField;に予め値を代入しておく

InputFeildControllerを付けているオブジェクトを選択すると下記画像の様になっている筈なので赤枠部分にInputFieldをドラッグ&ドロップすると代入できます。
代入出来ていればNullエラーが発生しなくなります。
イメージ説明

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/27 00:48

    ご回答ありがとうございます。
    回答いただいた方法を試したら解決いたしました。
    起動時のStart関数の呼び出されるタイミングが原因だったんですね。大変勉強になりました。

    キャンセル

0

まず、以下の2点を確認することから始めるといいと思います。

  1. どの変数が null だったのか
  2. どの GameObject で問題が起きているのか

後者を忘れがちですが、Unity ではここが重要です。
とりあえずエラーが出る該当行にブレークポイントを張ってデバッグ実行して前者を特定し、その時に後者も特定してみてください。

スクリプトのアタッチミス、オブジェクトのアサインミスも念頭に置いて調べてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/27 00:54

    ご回答ありがとうございます。
    教えていただいた記事も大変参考になりました。

    キャンセル

-2

nullがでるなら、nullかどうかチェックすればいいのでは

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/27 01:00

    ご回答ありがとうございます。
    すみません。私が変数のnullチェックを知りませんでした。
    勉強になりました。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る