どうもUSUです。以前から作成しているランゲームについてです。

やりたいこと

ボタンを押すとDB(MySql)のデータをリストに格納してUNITY画面に表示するというもの。

oreach文でNullエラーが出る DBを使ったゲーム制作
イメージ

今回の問題

しかしボタンをクリックすると1回目に「null reference exception object reference not set to an instance of an object …」 とエラーが… もちろんオブジェクトのアタッチ忘れなどはありません。

しかしもう一度クリックするとしっかり画面に表示されました。2回目に表示されているということはPHPやDBの通信、データの受け渡し自体には問題がない…

Nullエラーが出ている行は「 foreach(List terasu in terasulist)」の部分。ということは1度目にクリック時リストの中にデータが入っていない???

省略
    List<List> terasu = null;
    private bool OneTime = true;//一度だけ実行用

    public void Button_Push()
    {
        StartCoroutine("Access");//DBのデータを取得

        if (OneTime == true)//一度だけ表示
        {
            foreach (List terasu in terasulist)//ここでエラー
            {
              data = data + terasu.name + "\n";//dataにリストnameをすべて入れる
            }
       
            Text.GetComponent<Text>().text = "\n" + data;//テキストにdataを表示
           
            OneTime = false; 
        }
    }

    public class List //配列のリスト
    {
        public string time_id { get; set; }
        public string name { get; set; }
    }

    private IEnumerator Access() //表示したいデータの呼び出し
    {
        Debug.Log("Access");
        StartCoroutine(Post("http://localhost/〇〇〇.php"));//DBのテーブルを呼び出すPHP

        yield return 0;
    }

省略

原因の推測

色々調べていくとボタンを押した段階ではリスト内が空のままで、まだコルーチン(Access)が実行されていなさそう。または実行中?その後リストにデータが渡されている感じ。 

そして2回目押したときにはリスト内に値が入っているためにエラーが起きなかったという推測。

詳しい方であればデバッグで実行順序を見つつ最適な書き方ができるようですがまだ手探り状態のUSU・・・

解決方法

試しにボタンではなく、スタート関数内にコルーチンを書いてみると一発目から無事に表示されました( *´艸`) 

どうやらボタンと同時にコルーチンを呼び出しリスト内に入れ、それをテキストに表示するのは実行順序の違い?の問題か、Nullエラーが出ていたようです。

ちなみに筆者はゲーム上、ゴール判定時にコルーチンを呼び出しその後ボタンを押したら表示するようにしました。(下のコードはStart時に呼び出すもの)

省略
    List<List> terasu = null;
    private bool OneTime = true;//一度だけ実行用

    public void Start()
    {
        StartCoroutine("Access");//DBのデータを取得
    }

    public void Button_Push()
    {
        if (OneTime == true)//一度だけ表示
        {
            foreach (List terasu in terasulist)//ここでNullエラー
            {
              data = data + terasu.name + "\n";//dataにリストnameをすべて入れる
            }
       
            Text.GetComponent<Text>().text = "\n" + data;//テキストにdataを表示
           
            OneTime = false; 
        }
    }

    public class List //配列のリスト
    {
        public string time_id { get; set; }
        public string name { get; set; }
    }

    private IEnumerator Access() //表示したいデータの呼び出し
    {
        Debug.Log("Access");
        StartCoroutine(Post("http://localhost/〇〇〇.php"));//DBのテーブルを呼び出すPHP

        yield return 0;
    }

省略

同じような問題に直面した方がいれば是非参考にしてみてください!

参考にさせていただいたサイト

https://teratail.com/questions/v8sl5u5auxd3mi
https://ekulabo.com/check-null

おすすめ: