Unityでデータ保持用のクラスを扱う時に戸惑ったお話
こんにちは!
8月と9月に会社訪問やインターン、ハッカソンで忙しかったころんです。
今回はハッカソンでUnityを使った時にちょっと戸惑ったことがあったのでメモメモ
やりたかったこと
実装したかった流れは以下の通り。
- サーバーから取ってきたクライアント情報を保持するためのDictionaryが存在し、データ保持用クラスのメンバにはアイテム保持用のリストが宣言
- クライアント情報をDictionaryに追加し、クライアントごとにプレハブを生成
- 生成したプレハブをUnity上のInspectorで値を確認、編集できるようにしたい
今回はデータ構造が入れ子になってごちゃっていますが、許してw
でっこれの何が問題かというと、実行すると確かにアイテムデータは格納されているんですが、InspectorにはNoneと出ちゃうんですよね。
デバッグでInspectorをいじりたいこともありますし、これでは困ります。
検証コード
Unityバージョン:2017.1.1f1 Personal(5.6シリーズでも確認済み)
コードはこちら↓
ServerManager.csはサーバーからデータを取ってくることを想定。
ClientDataにはアイテムを格納するリストが存在し、専用のクラス(ItemData)も用意
ServerManager.csを空のGameObjectにアタッチ。ClientData.csはGameObjectに
アタッチした後プレハブ化し、ServerManagerのclientPrefabに適用しています。
確認のためにDictionaryの中身もDebug.Logで表示。
これを実行すると以下のようになります
Debugではきちんと値が格納されていることが分かります。
しかし、InspectorではItemListの中身はどれもNoneのままです。不思議ですねぇ~
原因
ItemData.csに継承しているMonoBehaivourが原因です。
MonoBehaivourを継承することにより、そのクラスはGameObjectとしての挙動を示します。そのため、ItemListにはデータ構造としてのItemDataではなく、GameObjectとしてのItemDataが格納されるため、値が表示されなくNoneとして表示されます。
Unity上でクラスを作ると自動的にMonoBehaivourが付いてくるので、気づかないでいたって感じです。
直し方
修正は簡単。ItemDataに継承されているMonoBehaivourを削除するだけです。
修正後のItemData.csと実行結果↓
これで無事にInspector上で値の確認ができました!
おわりに
今回は、データ構造が入れ子になっている時にMonoBehaivourが原因でInspectorで値が確認できない現象の解決を行いました。
本当は、ClientDataのMonoBehaivourも消せれば理想ですが、ServerManagerでGetComponentを使っているので残さないとエラーになります。
あんまり遭遇することがない事例だとは思いますが、お役に立てば幸いです。