Skip to content

Instantly share code, notes, and snippets.

@SabinT
Last active August 4, 2022 04:57
Show Gist options
  • Save SabinT/5e3fc2b0dcbca0e672ac7da13a8f9676 to your computer and use it in GitHub Desktop.
Save SabinT/5e3fc2b0dcbca0e672ac7da13a8f9676 to your computer and use it in GitHub Desktop.
Serializable string to generic map in Unity
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Lumic.Utils
{
/// <summary>
/// Assumes string keys.
/// Kind of works, use the +/- buttons on the "Keys". +/- Buttons on values list does't work.
/// Example usage:
/// [Serializable] public class MaterialMap : SerializableMap<Material> { } // create concrete class first
/// ...
/// public MaterialMap map = new MaterialMap(); // in MonoBehaviour
/// </summary>
[Serializable]
public class SerializableMap<TValue> : Dictionary<string, TValue>, ISerializationCallbackReceiver
{
private static int AutoKeyCount = 0;
[SerializeField] private List<string> keys = new List<string>();
[SerializeField] private List<TValue> values = new List<TValue>();
public void OnBeforeSerialize ()
{
this.keys.Clear();
this.values.Clear();
foreach (var pair in this)
{
this.keys.Add(pair.Key);
this.values.Add(pair.Value);
}
}
public void OnAfterDeserialize ()
{
this.Clear();
var count = keys.Count;
for (var i = 0; i < count; i++)
{
string k;
if (i == this.keys.Count - 1 && this.keys.Count > this.values.Count)
{
k = GetAutoKey();
} else
{
k = this.keys[i];
}
var v = (i > this.values.Count - 1) ? default(TValue) : this.values[i];
this.Add(k, v);
}
}
private static string GetAutoKey ()
{
return $"Element{AutoKeyCount++}";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment