- edited description
Property with [TypeFilter] cannot instantiate type that lacks Default Constructor
Odin Version: 3.0.4 (because as I reported in Error Report #782), the [TypeFilter] filter is broken in 3.0.5 and won’t instantiate anything at all.
1. What Happened
An ODIN serialized property that can support several different types gives you a drop down list of the compatible types, and indicates next to the type names if that type has no default constructor. Selecting a type that lacks a default constructor does not stop you from selecting it, and if selected, ODIN manages to successfully instantiate the type.
Problem is that when you add a [TypeFilter] attribute to the property to restrict the list of types, and then you select a type which does not have a default constructor, an exception is thrown and the type is not instantiated. The exception shown in the Console window in the Inspector is:
MissingMethodException: Default constructor not found for type MyTypeB
System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.RuntimeType.CreateInstanceSlow (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.RuntimeType.CreateInstanceDefaultCtor (System.Boolean publicOnly, System.Boolean skipCheckThis, System.Boolean fillCache, System.Threading.StackCrawlMark& stackMark) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Activator.CreateInstance (System.Type type, System.Boolean nonPublic) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Activator.CreateInstance (System.Type type) (at <695d1cc93cca45069c528c15c9fdd749>:0)
Sirenix.OdinInspector.Editor.Drawers.TypeFilterAttributeDrawer.AddResult (System.Collections.Generic.IEnumerable1[T] query) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Attribute Drawers/TypeFilterAttributeDrawer.cs:197) Sirenix.OdinInspector.Editor.Drawers.TypeFilterAttributeDrawer.DrawDropdown () (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Attribute Drawers/TypeFilterAttributeDrawer.cs:238) Sirenix.OdinInspector.Editor.Drawers.TypeFilterAttributeDrawer.DrawPropertyLayout (UnityEngine.GUIContent label) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Attribute Drawers/TypeFilterAttributeDrawer.cs:158) Sirenix.OdinInspector.Editor.OdinDrawer.CallNextDrawer (UnityEngine.GUIContent label) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinDrawer.cs:155) Sirenix.OdinInspector.Editor.Drawers.FixUnityNullDrawer
1[T].DrawPropertyLayout (UnityEngine.GUIContent label) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Misc Drawers/FixUnityNullDrawer.cs:87)
Sirenix.OdinInspector.Editor.OdinDrawer.CallNextDrawer (UnityEngine.GUIContent label) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinDrawer.cs:155)
Sirenix.OdinInspector.Editor.Drawers.ReferenceDrawer1[T].DrawPropertyLayout (UnityEngine.GUIContent label) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Misc Drawers/ReferenceDrawer.cs:118) Sirenix.OdinInspector.Editor.OdinDrawer.CallNextDrawer (UnityEngine.GUIContent label) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinDrawer.cs:155) Sirenix.OdinInspector.Editor.Drawers.PropertyContextMenuDrawer
1[T].DrawPropertyLayout (UnityEngine.GUIContent label) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Misc Drawers/PropertyContextMenuDrawer.cs:662)
Sirenix.OdinInspector.Editor.OdinDrawer.DrawProperty (UnityEngine.GUIContent label) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinDrawer.cs:109)
Sirenix.OdinInspector.Editor.InspectorProperty.Draw (UnityEngine.GUIContent defaultLabel) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/InspectorProperty.cs:807)
Rethrow as OdinPropertyException: This error occurred while being drawn by Odin.
Current IMGUI event: repaint
Odin Property Path: myFilteredType
Odin Drawer Chain:PropertyContextMenuDrawer<IMyType>
ReferenceDrawer<IMyType>
FixUnityNullDrawer<IMyType>
TypeFilterAttributeDrawer
NullableReferenceDrawer<IMyType>
CompositeDrawer.
UnityEngine.Debug:LogException(Exception)
Sirenix.OdinInspector.Editor.InspectorProperty:Draw(GUIContent) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/InspectorProperty.cs:884)
Sirenix.OdinInspector.Editor.InspectorProperty:Draw() (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/InspectorProperty.cs:695)
Sirenix.OdinInspector.Editor.Drawers.UnityObjectRootDrawer1:DrawPropertyLayout(GUIContent) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/Value Drawers/UnityObjectRootDrawer.cs:60) Sirenix.OdinInspector.Editor.OdinDrawer:CallNextDrawer(GUIContent) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinDrawer.cs:155) Sirenix.OdinInspector.Editor.Drawers.FixBrokenUnityObjectWrapperDrawer
1:DrawPropertyLayout(GUIContent) (at Assets/Plugins/Sirenix/Odin Inspector/Scripts/Editor/FixBrokenUnityObjectWrapperDrawer.cs:41)
Sirenix.OdinInspector.Editor.OdinDrawer:DrawProperty(GUIContent) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinDrawer.cs:109)
Sirenix.OdinInspector.Editor.InspectorProperty:Draw(GUIContent) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/InspectorProperty.cs:807)
Sirenix.OdinInspector.Editor.PropertyTree:DrawProperties() (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:485)
Sirenix.OdinInspector.Editor.PropertyTree:Draw(Boolean) (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Core/PropertyTree.cs:389)
Sirenix.OdinInspector.Editor.OdinEditor:DrawTree() (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinEditor.cs:93)
Sirenix.OdinInspector.Editor.OdinEditor:DrawOdinInspector() (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinEditor.cs:216)
Sirenix.OdinInspector.Editor.OdinEditor:OnInspectorGUI() (at Y:/Repositories/sirenix-development-framework/Sirenix Solution/Sirenix.OdinInspector.Editor/Drawers/OdinEditor.cs:85)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&)
2. How can we reproduce it?
Sample code and GIF below:
using System; using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; public class Test : SerializedMonoBehaviour { [TypeFilter(nameof(GetCompatibleTypes))] [SerializeField] private IMyType myFilteredType; [SerializeField] private IMyType myUnfilteredType; private IEnumerable<Type> GetCompatibleTypes() { return new [] {typeof(MyTypeA), typeof(MyTypeB)}; } } public interface IMyType { } public class MyTypeA : IMyType { } public class MyTypeB : IMyType { private MyTypeB(bool value) { } } public class MyTypeC : IMyType { }
Unity Version: 2021.1.5f1
Editor Only Mode: no.
Operating System: Windows 10
Comments (2)
-
reporter -
- changed status to resolved
Fixed for patch 3.0.6. Thanks for reporting this! If you'd like to try out the fix, please contact me on Discord and I'll get you a preview build.
- Log in to comment