LoginSignup
3
2

Unityで世界一シンプルなDictionaryシリアライズ

Last updated at Posted at 2023-12-11

この投稿は「K3 Advent Calendar 2023」の10日目の記事です

Unityの標準機能では、Dictionary型の変数はシリアライズされません。これは、多くのUnity開発者にとって課題となっています。
本記事では、SerializedDictionaryを使ってこの問題を解決する方法を紹介します。

コード

using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class SerializedDictionary<K, V> : Dictionary<K, V>, ISerializationCallbackReceiver
{
    [System.Serializable]
    internal class KeyValue
    {
        public K Key;
        public V Value;

        public KeyValue(K key, V value)
        {
            Key = key;
            Value = value;
        }
    }
    [SerializeField] List<KeyValue> m_list;

    public virtual K DefaultKey => default;
    void ISerializationCallbackReceiver.OnAfterDeserialize()
    {
        Clear();
        foreach (var item in m_list)
        {
            this[ContainsKey(item.Key) ? DefaultKey : item.Key] = item.Value;
        }
    }

    void ISerializationCallbackReceiver.OnBeforeSerialize()
    {
        m_list = new List<KeyValue>(Count);
        foreach (var kvp in this)
        {
            m_list.Add(new KeyValue(kvp.Key, kvp.Value));
        }
    }
}
[System.Serializable]
public class SerializedDictionary<V> : SerializedDictionary<string, V>
{
    public override string DefaultKey => string.Empty;
}
[System.Serializable]
public class SerializedDictionaryC<K, V> : SerializedDictionary<K, V> where K : new()
{
    public override K DefaultKey => new();
}

使用例

追加でCustomクラスは作る必要はなく、そのまま利用可能です。

[SerializeField] SerializedDictionary<int, string> m_PrimitiveDic;
[SerializeField] SerializedDictionary<string> m_StringDic;
[SerializeField] SerializedDictionaryC<Vector3, string> m_ClassDid;

Unity Editorでの表示

キーと値のペアが視覚的に編集可能な形式で表示されます。
image.png

本クラスの利点

Dictionaryをベースで継承しているため、Dictionaryに存在しているメソッドがそのまま使えます
また、インスペクターで用意にデータの編集も可能となっています。

他との比較

プロダクト Dictionary Inspector 補足
本プロダクト 継承 容易 コード数少ない
Core RP(Unity) IDictionary 不可 公式
neuecc/SerializableDictionary IDictionary 不可 高パフォーマンス / クラス別途定義
baba-s/UniSerializableDictionary 内部List 可能 クラス別途定義
UnityのSerializableFieldで連想配列(Dictinary)を扱いたい 配列 可能 Dictionary的扱い不可
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2