-
assigned issue to
System.Object polymorphism with array and non-array types breaks the inspector
Using Unity 2017.4.11f1 and Odin 2.0.5, when a field of type object, has it actual value changed while inspecting it, will break the inspector.
This behaviour occurs when the value types changes from an array type to a non array type, and vice versa.
Here is a simple component where this issue can be checked:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using System;
public class SimpleObjectFieldTest : SerializedMonoBehaviour
{
[SerializeField]
public object field;
[Button]
public void SetInt()
{
field = default(int);
}
[Button]
public void SetTransform()
{
field = transform;
}
[Button]
public void SetFloatArray()
{
field = new float[0];
}
[Button]
public void SetGameObjectArray()
{
field = new GameObject[0];
}
[Button]
public void PrintType()
{
Debug.LogFormat("[ObjectFieldTest] Field type: {0}.", (field == null) ? "null" : field.GetType().ToString());
}
}
I'm also attaching an attempt of solution using an Attribute (ObjectFieldTest, DrawAsTypeAttribute and DrawAsTypeAttributeDrawer).
Thanks for your time!
Comments (3)
-
-
- changed status to resolved
If you change values that change the "layout" of the data during the GUI loop (such as in a button press), you will get GUI layout errors. The issue can in this case be resolved by delaying the actual value change to a later time when it is "safe" to do:
[Button] public void SetInt() { EditorApplication.delayCall += () => field = default(int); }
Let me know if there's any other issues, or if the code above does not fix the problem at hand.
-
reporter I'm already trying to use the delayCall delegate, and is not working. For example, this simple script won't work either when changing some types:
using UnityEngine; using Sirenix.OdinInspector; #if UNITY_EDITOR using UnityEditor; #endif public class ObjectFieldTest : SerializedMonoBehaviour { #if UNITY_EDITOR [SerializeField] public object field; [Button] public void SetInt() => EditorApplication.delayCall += () => field = default(int); [Button] public void SetTransform() => EditorApplication.delayCall += () => field = transform; [Button] public void SetFloatArray() => EditorApplication.delayCall += () => field = new float[0]; [Button] public void SetGameObjectArray() => EditorApplication.delayCall += () => field = new GameObject[0]; [Button] public void Restore() => EditorApplication.delayCall += () => field = default(System.Object); [Button] public void PrintType() { UnityEngine.Debug.LogFormat("[ObjectFieldTest] Field type: {0}.", (field == null) ? "null" : field.GetType().ToString()); } #endif }
- Log in to comment