Unityでデータ保持用のクラスを扱う時に戸惑ったお話

こんにちは!
8月と9月に会社訪問やインターンハッカソンで忙しかったころんです。

 

今回はハッカソンでUnityを使った時にちょっと戸惑ったことがあったのでメモメモ 

 

やりたかったこ

 実装したかった流れは以下の通り。

 

  1. サーバーから取ってきたクライアント情報を保持するためのDictionaryが存在し、データ保持用クラスのメンバにはアイテム保持用のリストが宣言
  2. クライアント情報をDictionaryに追加し、クライアントごとにプレハブを生成
  3. 生成したプレハブをUnity上のInspectorで値を確認、編集できるようにしたい

 

今回はデータ構造が入れ子になってごちゃっていますが、許してw

でっこれの何が問題かというと、実行すると確かにアイテムデータは格納されているんですが、InspectorにはNoneと出ちゃうんですよね。

デバッグでInspectorをいじりたいこともありますし、これでは困ります。

 

検証コード

Unityバージョン:2017.1.1f1 Personal(5.6シリーズでも確認済み)

 

コードはこちら↓

ServerManager.csはサーバーからデータを取ってくることを想定。

ClientDataにはアイテムを格納するリストが存在し、専用のクラス(ItemData)も用意

gist.github.com

gist.github.com

gist.github.com

 ServerManager.csを空のGameObjectにアタッチ。ClientData.csはGameObjectに
アタッチした後プレハブ化し、ServerManagerのclientPrefabに適用しています。

確認のためにDictionaryの中身もDebug.Logで表示。

 

これを実行すると以下のようになります

f:id:Collonville:20170927011355j:plain

f:id:Collonville:20170927011359j:plain

Debugではきちんと値が格納されていることが分かります。

しかし、InspectorではItemListの中身はどれもNoneのままです。不思議ですねぇ~

 

原因

ItemData.csに継承しているMonoBehaivourが原因です。

MonoBehaivourを継承することにより、そのクラスはGameObjectとしての挙動を示します。そのため、ItemListにはデータ構造としてのItemDataではなく、GameObjectとしてのItemDataが格納されるため、値が表示されなくNoneとして表示されます。

 

Unity上でクラスを作ると自動的にMonoBehaivourが付いてくるので、気づかないでいたって感じです。

 

docs.unity3d.com

 

kan-kikuchi.hatenablog.com

 

直し方

修正は簡単。ItemDataに継承されているMonoBehaivourを削除するだけです。

修正後のItemData.csと実行結果↓

gist.github.com

f:id:Collonville:20170927015223j:plain

これで無事にInspector上で値の確認ができました!

 

おわりに

今回は、データ構造が入れ子になっている時にMonoBehaivourが原因でInspectorで値が確認できない現象の解決を行いました。

 

本当は、ClientDataのMonoBehaivourも消せれば理想ですが、ServerManagerでGetComponentを使っているので残さないとエラーになります。

 

あんまり遭遇することがない事例だとは思いますが、お役に立てば幸いです。