【Unity】Dictionary型をインスペクターで表示する
今回のやること
今回の目標はUnityのインスペクター上でDictionary型を編集できるようにします。
最終的な見た目は以下のようになります。
今回のゴール
Dictionary型はキーとバリューの2つの変数の型を指定します。この部分は自分で好きな型を指定できるような汎用性の良いプログラムで作成していきます。
開発環境
- Unity6
- VisualStudio2022
制作
今回作成したソースコードは以下のようになります。そこまで、難しいくはないと思います。
using UnityEngine;
using System.Collections.Generic;
using System;
[Serializable]
public class SerializeDictionary<TKey, TValue>
{
[SerializeField] private List<DicElement> _dicElements = new List<DicElement>();
private Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
[Serializable]
public class DicElement
{
public TKey Key;
public TValue Value;
public DicElement(TKey key, TValue value)
{
Key = key;
Value = value;
}
}
public Dictionary<TKey, TValue> GetDictionary
{
get
{
if(_dicElements != null)
{
_dictionary.Clear();
foreach(var element in _dicElements)
{
_dictionary.Add(element.Key, element.Value);
}
return _dictionary;
}
return null;
}
}
}
[Serializable]
public class SerializeDictionary<TKey, TValue>
{
省略
}
ここでは、クラスに[Serializable]
を付けてクラス内をインスペクターで編集できるようにする。
変数の型を自由に設定できる汎用性の良いモノにしたいため、ジェネリックを使いました。
[Serializable]
public class DicElement
{
public TKey Key;
public TValue Value;
public DicElement(TKey key, TValue value)
{
Key = key;
Value = value;
}
}
ここでは、先程と同様[Serializable]を付けてキーとバリューをインスペクターで編集できるようにします。そして、要素を追加するときにコンストラクタを用いました。
要素を追加するということですが、後から(ゲーム中等)要素を追加するときに使います。
[SerializeField] private List<DicElement> _dicElements = new List<DicElement>();
private Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
ここでは、先程の「DicElementクラス」を複数作成するためリスト型で作成します。
そして、このリストをDictionary型
に変換するための「_dictionary」を作成します。
public Dictionary<TKey, TValue> GetDictionary
{
get
{
if(_dicElements != null)
{
_dictionary.Clear();
foreach(var element in _dicElements)
{
_dictionary.Add(element.Key, element.Value);
}
return _dictionary;
}
return null;
}
}
ここでは、作成したDictionary型のデータを取得する際にgetのプロパティを作っています。
処理内容は作成したリストの中身が空じゃなかったら、リストの要素を_dictionaryに格納してそれを取得する感じです。
要素を後から追加するときは
public void AddElement(TKey key, TValue value)
{
if(_dicElements != null)
{
_dicElements.Add(new DicElement(key, value));
}
}
要素を追加するときは、_dicElements
のNullチェックをしてDicElement
のインスタンスを作成し、
_dicElements
リストに追加すればOKです。
使用方法
using UnityEngine;
public class Controller : MonoBehaviour
{
//今回はItemという独自クラスとアイテムの個数を変数として指定
[SerializeField] private SerializeDictionary<Item, int> _ItemBox;
void Start()
{
//Dictionaryのすべての要素(キー)を取得
foreach(var key in _ItemBox.GetDictionary.keys)
{
Debug.Log(key.ItemName);
}
}
}
記入後、エディタに戻るとItemBoxという変数ができて、要素の追加等ができます。
追加し、データを記入して実行すると、コンソールに追加したデータのキーが見れると思います。
さいごに
今回はUnityでDictionary型をインスペクターで編集できるようにしました。
特に、ジェネリックをあまり使ったことがなかったので、執筆した私自身もかなり勉強になりました。
もし、間違いや改良できるところがありましたら、指摘していただけると大変助かります。
最後まで記事を読んでいただきありがとうございました。
Discussion