Property with [TypeFilter] cannot instantiate type that lacks Default Constructor

Issue #784 resolved
Nicholas Aitken created an issue

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.FixUnityNullDrawer1[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.PropertyContextMenuDrawer1[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.FixBrokenUnityObjectWrapperDrawer1: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)

  1. Tor Esa Vestergaard

    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.

  2. Log in to comment