LoginSignup
24
24

More than 5 years have passed since last update.

続・UnityのInspectorで扱えるDictionary

Last updated at Posted at 2014-06-27

前回の投稿
http://qiita.com/k_yanase/items/fb64ccfe1c14567a907d
でバイナリデータにシリアライズできるかもと思って試したところうまくいったので強化してみた

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
//using System.Reflection;

namespace Serialize {

    [System.Serializable]
    public class TableBase<TKey, TValue, TPair> where TPair : KeyAndValue<TKey, TValue> , new (){
        [SerializeField]
        protected List<TPair> list;                     
        protected Dictionary<TKey, TValue> table;       

        public TableBase () {
            list = new List<TPair>();
        }

        public Dictionary<TKey, TValue> GetTable () {
            if (table == null) {
                table = ConvertListToDictionary(list);
            }
            return table;
        }

        public TValue GetValue (TKey key) {
            if(GetTable ().Keys.Contains(key)){
                return GetTable ()[key];
            }
            //Debug.LogError(key +" は存在しないKeyです");
            return default(TValue);
        }

        public void SetValue (TKey key, TValue value) {
            if(GetTable ().Keys.Contains(key)){
                //Debug.Log ("SetValue() Change Value.");
                table[key] = value;
            }else {
                //Debug.Log ("SetValue() Add new table.");
                table.Add(key, value);
            }
        }

        public void Reset () {
            table = new Dictionary<TKey, TValue>();
            list = new List<TPair>();
        }
        public void Apply () {
            list = ConvertDictionaryToList(table);
        }

        static Dictionary<TKey, TValue> ConvertListToDictionary (List<TPair> list) {
            Dictionary<TKey, TValue> dic = new Dictionary<TKey, TValue> ();
            foreach(KeyAndValue<TKey, TValue> pair in list){
                dic.Add(pair.Key, pair.Value);
            }
            return dic;
        }

        static List<TPair> ConvertDictionaryToList (Dictionary<TKey, TValue> table) {
            List<TPair> list = new List<TPair>();

            if(table != null){
                foreach(KeyValuePair<TKey, TValue> pair in table){
                    TPair type = new TPair();
                    type.Key = pair.Key;
                    type.Value = pair.Value;
                    list.Add(type);
                }
            }
            return list;
        }
    }

    /// <summary>
    /// シリアル化できる、KeyValuePairに代わる構造体
    /// </summary>
    [System.Serializable]
    public class KeyAndValue<TKey, TValue>
    {
        public TKey Key;
        public TValue Value;
    }
}

大きな変更点は
・Apply()メソッドが追加されたこと
・KeyAndValueのコンストラクタがなくなったこと
です

GetTableで取得した取得したディクショナリに変更を加えた後、BinaryFommaterなどでバイナリデータに保存したり、UnityのScriptableObjectに変更を保存する前にApplyメソッドを呼ぶことで、
protected Dictionary<TKey, TValue> table;
に記録されたデータをシリアライズ可能なList型の
protected List<TPair> list;
に再度適用することが出来るので、保存も可能になりました。

そのかわり、変換の都合でコンストラクタでKeyAndValueを作るのか少しめんどくさくなってますが、実際のところDictionaryクラスを通して編集することになるので、あまり影響はないと思います

また、GetTableを通してDictionaryとして編集が可能なので、Dictionaryクラスの便利な機能も使うことが可能です

24
24
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
24
24