Hi and thank you!
I love the simple serializable output your dictionary gives after serialization. Well done! Also well written code, and adding new Dictionary definitions and PropertyDrawers is a breeze!
However, i came here to report an issue.
First though, let me request a feature:
Please wrap your package classes in a namespace, like this:
namespace mathieuleber
{
public abstract class SerializableDictionaryBase<TKey, .....
{
......
}
Same for the SerializableDictionaryPropertyDrawer class. Then creating new Definitions and PropertyDrawers will change slightly…
[Serializable]
public class StringBoolDictionary : mathieuleber.SerializableDictionary<string, bool> {}
and
[CustomPropertyDrawer(typeof(StringBoolDictionary))]
public class AnySerializableDictionaryPropertyDrawer : mathieuleber.SerializableDictionaryPropertyDrawer {}
Please do this for the assetstore package, as projects might contain multiple SerializableDictionary classes (like mine does), and some of them inside locked packages, so you need to have a unique handle on your package. Adding to your implementation every time we update from asset store is just extra work for us users.
Now a backstory to the errors i came to report:
When first looking for SerializableDictionary, i followed this implementation, but wondered why its so complex and the serializable output it gives is so extremely bloated.
As the author ( @vexe ) mentions, the “logical” implementation (one which you’re also using) was causing some unexplained errors, and other users had the same experience. More in this thread.
I then later found you Dictionary implementation in assetstore, and decided to give it a try. You can read more on how that went at the end of the last thread link i gave you.
Now let me describe what i did, after which the error started to appear:
- added some custom definitions for basic types (StringBoolDictionary, StringIntDictionary, …)
- added custom PropertyDrawers for them ([CustomPropertyDrawer(typeof(StringBoolDictionary))], …)
- Meanwhile, tinkered for a month with personal project, adding more simple type SerializableDictionaries and respective PropertyDrawers.
As you can see, no changes to your implementation at all. Weird observation - first time i added just few definitions, everything worked well (both in the scripting world, and in the custom inspector world). At some point, i guess after adding another definition for a basic type/basic type dictionary, i could not open their inspector property drawers, and after selecting the object in hierarchy, instead of the classic [+] sign add element, i got no custom editor output (not even default inspector eg DrawDefaultInspector() if you know what i mean) just empty component view with fold/unfold arrow pointing down/right.
I tried replicating the issue using new unit-test project, using just your package and adding definitions and property drawers. I was not successful to replicate the issue (sidenote: this seems to suggest, that the new update of your package has nothing to do with fixing the error).
Next, ill paste here the 2 errors i got in console, they kept repeating, i guess that’s just GUI repaint stuff:
NullReferenceException: Object reference not set to an instance of an object
at mathieuleber.SerializableDictionaryPropertyDrawer+<EnumerateEntries>c__Iterator0.MoveNext () [0x00028] in #PROJECT_FOLDER#\Assets\Scripts\mathieuleber\SerializableDictionary\Editor\SerializableDictionaryPropertyDrawer.cs:538
at mathieuleber.SerializableDictionaryPropertyDrawer.GetPropertyHeight (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) [0x00080] in #PROJECT_FOLDER#\Assets\Scripts\mathieuleber\SerializableDictionary\Editor\SerializableDictionaryPropertyDrawer.cs:309
at UnityEditor.PropertyDrawer.GetPropertyHeightSafe (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) [0x0000f] in C:\buildslave\unity\build\Editor\Mono\ScriptAttributeGUI\PropertyDrawer.cs:36
at UnityEditor.PropertyHandler.GetHeight (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) [0x0008b] in C:\buildslave\unity\build\Editor\Mono\ScriptAttributeGUI\PropertyHandler.cs:216
at UnityEditor.EditorGUI.GetPropertyHeightInternal (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) [0x0000a] in C:\buildslave\unity\build\Editor\Mono\EditorGUI.cs:5643
at UnityEditor.EditorGUI.GetPropertyHeight (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) [0x00004] in C:\buildslave\unity\build\artifacts\generated\common\editor\EditorGUIBindings.gen.cs:936
at UnityEditor.Editor.GetOptimizedGUIBlockImplementation (Boolean isDirty, Boolean isVisible, UnityEditor.OptimizedGUIBlock& block, System.Single& height) [0x000f6] in C:\buildslave\unity\build\artifacts\generated\common\editor\EditorBindings.gen.cs:259
at UnityEditor.GenericInspector.GetOptimizedGUIBlock (Boolean isDirty, Boolean isVisible, UnityEditor.OptimizedGUIBlock& block, System.Single& height) [0x00007] in C:\buildslave\unity\build\Editor\Mono\Inspector\GenericInspector.cs:13
at UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor[] editors, Int32 editorIndex, Boolean rebuildOptimizedGUIBlock, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect) [0x00331] in C:\buildslave\unity\build\Editor\Mono\Inspector\InspectorWindow.cs:1207
at UnityEditor.InspectorWindow.DrawEditors (UnityEditor.Editor[] editors) [0x0015d] in C:\buildslave\unity\build\Editor\Mono\Inspector\InspectorWindow.cs:1022
at UnityEditor.InspectorWindow.OnGUI () [0x00074] in C:\buildslave\unity\build\Editor\Mono\Inspector\InspectorWindow.cs:361
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x000d0] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222
Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x000eb] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:232
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MethodBase.cs:115
at UnityEditor.HostView.Invoke (System.String methodName, System.Object obj) [0x00013] in C:\buildslave\unity\build\Editor\Mono\HostView.cs:295
at UnityEditor.HostView.Invoke (System.String methodName) [0x00009] in C:\buildslave\unity\build\Editor\Mono\HostView.cs:288
at UnityEditor.HostView.InvokeOnGUI (Rect onGUIPosition) [0x000e0] in C:\buildslave\unity\build\Editor\Mono\HostView.cs:255
UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object)
UnityEngine.DebugLogHandler:LogException(Exception, Object)
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:LogException(Exception)
UnityEngine.Experimental.UIElements.IMGUIContainer:smile:oOnGUI(Event) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\IMGUIContainer.cs:189)
UnityEngine.Experimental.UIElements.IMGUIContainer:HandleIMGUIEvent(Event) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\IMGUIContainer.cs:330)
UnityEngine.Experimental.UIElements.IMGUIContainer:smile:oRepaint(IStylePainter) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\IMGUIContainer.cs:68)
UnityEngine.Experimental.UIElements.Panel:PaintSubTree(Event, VisualElement, Matrix4x4, Rect) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\Panel.cs:532)
UnityEngine.Experimental.UIElements.Panel:PaintSubTreeChildren(Event, VisualElement, Matrix4x4, Rect) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\Panel.cs:547)
UnityEngine.Experimental.UIElements.Panel:PaintSubTree(Event, VisualElement, Matrix4x4, Rect) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\Panel.cs:536)
UnityEngine.Experimental.UIElements.Panel:Repaint(Event) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\Panel.cs:564)
UnityEngine.Experimental.UIElements.UIElementsUtility:smile:oDispatch(BaseVisualElementPanel) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\UIElementsUtility.cs:236)
UnityEngine.Experimental.UIElements.UIElementsUtility:ProcessEvent(Int32, IntPtr) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\UIElementsUtility.cs:78)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) (at C:\buildslave\unity\build\Runtime\IMGUI\Managed\GUIUtility.cs:175)
(Filename: Assets/Scripts/mathieuleber/SerializableDictionary/Editor/SerializableDictionaryPropertyDrawer.cs Line: 538)
GUI Error: You are pushing more GUIClips than you are popping. Make sure they are balanced)
UnityEngine.DebugLogHandler:Internal_Log(LogType, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:LogError(Object)
UnityEngine.Experimental.UIElements.IMGUIContainer:smile:oOnGUI(Event) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\IMGUIContainer.cs:277)
UnityEngine.Experimental.UIElements.IMGUIContainer:HandleIMGUIEvent(Event) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\IMGUIContainer.cs:330)
UnityEngine.Experimental.UIElements.IMGUIContainer:smile:oRepaint(IStylePainter) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\IMGUIContainer.cs:68)
UnityEngine.Experimental.UIElements.Panel:PaintSubTree(Event, VisualElement, Matrix4x4, Rect) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\Panel.cs:532)
UnityEngine.Experimental.UIElements.Panel:PaintSubTreeChildren(Event, VisualElement, Matrix4x4, Rect) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\Panel.cs:547)
UnityEngine.Experimental.UIElements.Panel:PaintSubTree(Event, VisualElement, Matrix4x4, Rect) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\Panel.cs:536)
UnityEngine.Experimental.UIElements.Panel:Repaint(Event) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\Panel.cs:564)
UnityEngine.Experimental.UIElements.UIElementsUtility:smile:oDispatch(BaseVisualElementPanel) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\UIElementsUtility.cs:236)
UnityEngine.Experimental.UIElements.UIElementsUtility:ProcessEvent(Int32, IntPtr) (at C:\buildslave\unity\build\Runtime\UIElements\Managed\UIElementsUtility.cs:78)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) (at C:\buildslave\unity\build\Runtime\IMGUI\Managed\GUIUtility.cs:175)
(Filename: C:/buildslave/unity/build/Runtime/UIElements/Managed/IMGUIContainer.cs Line: 277)
And finally, how this error “disappeared”:
I’ve redownloaded your assetstore package, and updated my project files. Also i noticed there was a new update in May to your package (i was using package from April/2018), however i don’t think it was the update that finally “fixed” the error. After the update, i re-added the PropertyDrawer and Custom SerializableDictionary definitions i required in my project, oh and the namespace of course…) - so literally the code was in the same place as it was when it was giving errors (minus the update).
I hope this helps somehow. I can see the errors being internal Unity stuff, so i dont think you can do anything to fix that, but, yeah, the link i posted earlier says the same thing, and thats why @vexe made his own SerializableDictionary implementation (which i dont like, the serialized output it gives is too long for my use-case). So the issue stays. I dont know, how and if you could in any way fix it, its so difficult to reproduce.
Best of luck!
Ask if any questions,
Cheers!