Unity-SerializableDictionary icon indicating copy to clipboard operation
Unity-SerializableDictionary copied to clipboard

There is an already better solution inside Unity URP package - try to serach inside the pachage itself

Open studentutu opened this issue 5 years ago • 4 comments
trafficstars

Try to get the SerializedUnityDicitonary from URP package

studentutu avatar Sep 16 '20 11:09 studentutu

Did they really only implement this into the URP package instead of making it a separate package? :unamused:
Is there maybe some documentation on this or is it only meant to be used internally? I've tried Google but came up empty apart from the hundreds of threads that have been created over the years asking how to serialize dictionaries in Unity...

In the meantime I've quickly turned azix's plugin into a UPM package myself which can be imported via https://github.com/RobertClassen/Unity-SerializableDictionary.git#UPM.
I've also opened a Pull Request, in case azix is still around (last activity on December 10, 2019) and interested: https://github.com/azixMcAze/Unity-SerializableDictionary/pull/20

RobertClassen avatar Oct 01 '20 19:10 RobertClassen

SerializedDictionary in UnityEngine.Rendering

Code:

using System;
using System.Collections.Generic;

namespace UnityEngine.Rendering
{
    //
    // Unity can't serialize Dictionary so here's a custom wrapper that does. Note that you have to
    // extend it before it can be serialized as Unity won't serialized generic-based types either.
    //
    // Example:
    //   public sealed class MyDictionary : SerializedDictionary<KeyType, ValueType> {}
    //
    /// <summary>
    /// Serialized Dictionary
    /// </summary>
    /// <typeparam name="K">Key Type</typeparam>
    /// <typeparam name="V">Value Type</typeparam>
    [Serializable]
    public class SerializedDictionary<K, V> : Dictionary<K, V>, ISerializationCallbackReceiver
    {
        [SerializeField]
        List<K> m_Keys = new List<K>();

        [SerializeField]
        List<V> m_Values = new List<V>();

        /// <summary>
        /// OnBeforeSerialize implementation.
        /// </summary>
        public void OnBeforeSerialize()
        {
            m_Keys.Clear();
            m_Values.Clear();

            foreach (var kvp in this)
            {
                m_Keys.Add(kvp.Key);
                m_Values.Add(kvp.Value);
            }
        }

        /// <summary>
        /// OnAfterDeserialize implementation.
        /// </summary>
        public void OnAfterDeserialize()
        {
            for (int i = 0; i < m_Keys.Count; i++)
                Add(m_Keys[i], m_Values[i]);

            m_Keys.Clear();
            m_Values.Clear();
        }
    }
}

RWOverdijk avatar Oct 09 '20 13:10 RWOverdijk

In which Unity version is this?
The latest Unity version I currently have installed is 2020.1.3 but it seems I that can't access this class there.
I found this documentation page but unfortunately it does not say when this was introduced.

The fact that this is only in "UnityEngine.Rendering" instead of just "UnityEngine" tells me that this is only meant to be used internally because the Unity Serializer still to this day cannot handle Dictionaries natively (without having to loop around by using the "ISerializationCallbackReceiver" interface) which is a complete travesty in and of itself!

I've also found no CustomEditor for this implementation (at least in the documentation linked above), meaning that the Inspector will probably just display the keys and values as two Lists instead of side-by-side and without any "Add" or "Remove" buttons, making azix's implementation the better solution (which also contains a "SerializableHashSet" class).

RobertClassen avatar Oct 09 '20 15:10 RobertClassen

I don't think you're supposed to use it. I was just pointing to where the code from that one random comment can be found.

It doesn't come with a custom editor, but rather with two List fields.

RWOverdijk avatar Oct 14 '20 15:10 RWOverdijk