Simple Dictionary<int, MyClass> explodes at runtime

Issue #121 resolved
Scott Richmond created an issue
public class SomeMonoB : MonoBehavior {
    [ShowInInspector]
    public Dictionary<int, GroundTypeData> GroundMaterials = new Dictionary<int, GroundTypeData>();
}

public class GroundTypeData
{
    public float Grip = 1.0f;
    public float Drag = 0.1f;

    public float MaxDisplacementMeters = 0.2f;
}

Outside of play mode this code seems to work fine - I can do all the expected things like adding and removing data. However it won't serialize out and when I hit play the game explodes with errors:

An exception was thrown while trying to update the property at path: PhysicsTerrains.
UnityEngine.Debug:Log(Object)
Sirenix.OdinInspector.Editor.PropertyTree`1:UpdateProperty(InspectorProperty) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:2312)
Sirenix.OdinInspector.Editor.PropertyTree`1:UpdateTree() (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:1988)
Sirenix.OdinInspector.Editor.InspectorUtilities:BeginDrawPropertyTree(PropertyTree, Boolean) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/InspectorUtilities.cs:169)
Sirenix.OdinInspector.Editor.PropertyTree:Draw(Boolean) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:142)
Sirenix.OdinInspector.Editor.OdinEditor:OnInspectorGUI() (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinEditor.cs:183)
UnityEditor.DockArea:OnGUI()

ArgumentException: Only single dimension arrays are supported.
System.Array.System.Collections.IList.get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System/Array.cs:305)
Sirenix.OdinInspector.Editor.PropertyWeakListElementValueEntry`2[UnityEngine.Terrain[,],System.Object].GetActualValue (UnityEngine.Terrain[,] parent) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/Value Entries/PropertyWeakListElementValueEntry.cs:39)
Sirenix.OdinInspector.Editor.PropertyValueEntry`2[UnityEngine.Terrain[,],System.Object].UpdateValues () (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/Value Entries/PropertyValueEntry.cs:1015)
Sirenix.OdinInspector.Editor.PropertyValueEntry.Update () (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/Value Entries/PropertyValueEntry.cs:208)
Sirenix.OdinInspector.Editor.InspectorProperty.UpdateValueEntry () (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/InspectorProperty.cs:433)
Sirenix.OdinInspector.Editor.InspectorProperty.Update (Boolean forceUpdate) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/InspectorProperty.cs:267)
Sirenix.OdinInspector.Editor.PropertyChildren.Get (Int32 index) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/Children/PropertyChildren.cs:179)
Sirenix.OdinInspector.Editor.PropertyTree`1[StampBasedDeformerv4].UpdateProperty (Sirenix.OdinInspector.Editor.InspectorProperty property) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:2306)
UnityEngine.Debug:LogException(Exception)
Sirenix.OdinInspector.Editor.PropertyTree`1:UpdateProperty(InspectorProperty) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:2313)
Sirenix.OdinInspector.Editor.PropertyTree`1:UpdateTree() (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:1988)
Sirenix.OdinInspector.Editor.InspectorUtilities:BeginDrawPropertyTree(PropertyTree, Boolean) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/InspectorUtilities.cs:169)
Sirenix.OdinInspector.Editor.PropertyTree:Draw(Boolean) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:142)
Sirenix.OdinInspector.Editor.OdinEditor:OnInspectorGUI() (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinEditor.cs:183)
UnityEditor.DockArea:OnGUI()

NullReferenceException: Object reference not set to an instance of an object
Sirenix.OdinInspector.Editor.InspectorProperty.NextProperty (Boolean includeChildren) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/InspectorProperty.cs:217)
Sirenix.OdinInspector.Editor.PropertyTree`1+<EnumerateTree>d__74[StampBasedDeformerv4].MoveNext () (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:2201)
Sirenix.OdinInspector.Editor.PropertyTree.ApplyChanges () (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:274)
Sirenix.OdinInspector.Editor.InspectorUtilities.EndDrawPropertyTree (Sirenix.OdinInspector.Editor.PropertyTree tree) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Misc/InspectorUtilities.cs:226)
Sirenix.OdinInspector.Editor.PropertyTree.Draw (Boolean applyUndo) (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:144)
Sirenix.OdinInspector.Editor.OdinEditor.OnInspectorGUI () (at C:/Users/Bjarke/Desktop/Projects/Sirenix/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinEditor.cs:183)
UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor editor, Int32 editorIndex, Boolean rebuildOptimizedGUIBlock, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1229)
UnityEditor.DockArea:OnGUI()

Comments (2)

  1. Tor Esa Vestergaard

    Hi Scott,

    First, the error you're seeing is not actually related to the dictionary at all. Somewhere, you have a two-dimensional Terrain[,] array inspected by Odin - however, Odin does not yet support two-dimensional arrays in the inspector - we can't even update two-dimensional arrays properly yet (though clearly, we need to provide better feedback than throwing exceptions - we'll make a note of that). You'll have to mark the field or property that contains a Terrain[,] instance with the [ExcludeDataFromInspector] attribute. Odin can (and will) serialize it if you tell it to, but it will not inspect it (yet).

    Second, your dictionary in the example code will not actually be saved at all, and all its data will be lost whenever a reload occurs, such as when play mode is entered. You have merely marked it with [ShowInInspector] - meaning it will be shown, but not necessarily saved. It will only be saved if your type is specially serialized by Odin, and currently it is not. You can't use Odin's serialization without inheriting your class from a special type, such as SerializedMonoBehaviour or SerializedScriptableObject, or implementing it manually yourself. See our manual for further information.

  2. Scott Richmond reporter

    Indeed! I realised the same just now and came here to correct myself. I have resolved the problem exactly as described. Cheers!

  3. Log in to comment