Ordered dictionary for Unity

When working on projects it is often useful to have some sort of asset that maps values to keys. Since Unity doesn’t currently support the serialization of dictionaries this is something that I either try to avoid needing entirely or that I end up having to reinvent each time by implementing the ISerializationCallbackReceiver interface following the example in Unity’s documentation.

To ease this workflow I implemented a custom ScriptableObject class which provided reusable ordered dictionary editing. Whilst this was a reasonably good solution for a lot of use cases it was difficult to use with a recent project because it was difficult to maintain all of the separate .asset files.

One of the features that I really wanted was to have each key and value drawn to the editor UI using EditorGUI.PropertyField since this way they are drawn using custom property drawers. This is nice because it allows specialized editors to be developed independently from the ordered dictionary itself.

Screenshot of ordered dictionary

The biggest difficulty with this was allowing for the “New Entry” input along the bottom. I found that the best solution was to define a singleton ScriptableObject that holds one occurrence of the key/value pair so that it can be drawn using the same property drawers as the main control.

The same “New Entry” input object is used for all ordered dictionary fields (of the same key/value types). The user can only be inputting a new entry on one ordered dictionary field at any given time. Each time the user clicks the button to start inputting a new entry the “New Entry” input object is cleared and becomes associated with the ‘now’ active ordered dictionary using its control ID.

Since Unity’s serialization system doesn’t support the serialization of generic types it is necessary to create a little boilerplate for each unique key/value pair type. I created a little online tool to automate the creation of this.

// Boilerplate for the editable entry singleton.
public sealed class EditableOrderedDictionary_string_Sprite
    : EditableEntry<OrderedDictionary_string_Sprite>
{
}

// Boilerplate for the serializable ordered dictionary.
[Serializable]
[EditableEntry(typeof(EditableOrderedDictionary_string_Sprite))]
public sealed class OrderedDictionary_string_Sprite
    : OrderedDictionary<string, Sprite>
{
}

With the above boilerplate a custom sprite library asset can then be created with ease:

[CreateAssetMenu]
public sealed class SpriteLibraryAsset : ScriptableObject
{
    public OrderedDictionary_string_Sprite sprites;
}

And of course, the same can be done using any type for the ordered dictionary’s key and value so long as they can be serialized by Unity. As with regular dictionaries; it is a good idea to have custom value types (structs) implement the IEquatable<T> interface so that it doesn’t generate excessive amounts of garbage by boxing the values of keys over and over again.

If Unity add serialization support for generic types then the above boilerplate would nolonger be necessary since OrderedDictionary<string, Sprite> could be used directly.

Whilst the ability to explicitly order the entries of a dictionary isn’t useful for all use cases; it does help to provide a consistent editing experience. It’s also allows the people that input their data to organize the entries as desired.

I released this library as open source on Bitbucket 💗