AnnulusGames / Alchemy

Provides a rich set of editor extensions and serialization extensions for Unity.
https://annulusgames.github.io/Alchemy/
MIT License
556 stars 33 forks source link

NullReferenceException when inspecting derived class with private array-like field from base class #64

Closed yuyu0127 closed 7 months ago

yuyu0127 commented 7 months ago

Issue Description

I am encountering a NullReferenceException when attempting to inspect a derived class that includes a private array or list field from its base class in the Inspector. This issue occurs under specific circumstances described below.

Exception

NullReferenceException: Object reference not set to an instance of an object
Alchemy.Editor.SerializedPropertyExtensions.GetPropertyType (UnityEditor.SerializedProperty property, System.Boolean isCollectionType) (at Assets/Alchemy/Editor/Internal/SerializedPropertyExtensions.cs:122)
Alchemy.Editor.Elements.AlchemyPropertyField..ctor (UnityEditor.SerializedProperty property, System.Type type, System.Boolean isArrayElement) (at Assets/Alchemy/Editor/Elements/AlchemyPropertyField.cs:34)
Alchemy.Editor.InspectorHelper.CreateMemberElement (UnityEditor.SerializedObject serializedObject, System.Object target, System.Reflection.MemberInfo memberInfo, System.Func`2[T,TResult] findPropertyFunc) (at Assets/Alchemy/Editor/Internal/InspectorHelper.cs:222)
Alchemy.Editor.InspectorHelper.BuildElements (UnityEditor.SerializedObject serializedObject, UnityEngine.UIElements.VisualElement rootElement, System.Object target, System.Func`2[T,TResult] findPropertyFunc) (at Assets/Alchemy/Editor/Internal/InspectorHelper.cs:133)
Alchemy.Editor.Elements.AlchemyPropertyField..ctor (UnityEditor.SerializedProperty property, System.Type type, System.Boolean isArrayElement) (at Assets/Alchemy/Editor/Elements/AlchemyPropertyField.cs:59)
Alchemy.Editor.InspectorHelper.CreateMemberElement (UnityEditor.SerializedObject serializedObject, System.Object target, System.Reflection.MemberInfo memberInfo, System.Func`2[T,TResult] findPropertyFunc) (at Assets/Alchemy/Editor/Internal/InspectorHelper.cs:222)
Alchemy.Editor.InspectorHelper.BuildElements (UnityEditor.SerializedObject serializedObject, UnityEngine.UIElements.VisualElement rootElement, System.Object target, System.Func`2[T,TResult] findPropertyFunc) (at Assets/Alchemy/Editor/Internal/InspectorHelper.cs:133)
Alchemy.Editor.AlchemyEditor.CreateInspectorGUI () (at Assets/Alchemy/Editor/AlchemyEditor.cs:95)
UnityEditor.UIElements.InspectorElement.CreateInspectorElementUsingUIToolkit (UnityEditor.Editor targetEditor) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:562)
UnityEditor.UIElements.InspectorElement.CreateInspectorElementFromSerializedObject (UnityEditor.SerializedObject bindObject) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:465)
UnityEditor.UIElements.InspectorElement.ExecuteDefaultActionAtTarget (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:374)
UnityEngine.UIElements.CallbackEventHandler.HandleEvent (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:281)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtCurrentTargetAndPhase (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:189)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtTargetPhase (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:175)
UnityEngine.UIElements.CallbackEventHandler.HandleEventAtTargetAndDefaultPhase (UnityEngine.UIElements.EventBase evt) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/Events/EventHandler.cs:180)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.SendBindingEvent[TEventType] (TEventType evt, UnityEngine.UIElements.VisualElement target) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:85)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindTree (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:95)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.ContinueBinding (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:40)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.Bind (UnityEngine.UIElements.VisualElement element) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:31)
UnityEditor.UIElements.Bindings.DefaultSerializedObjectBindingImplementation.Bind (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedObject obj) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:816)
UnityEditor.UIElements.BindingExtensions.Bind (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedObject obj) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Bindings/BindingsInterface.cs:56)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.SerializedObject obj, UnityEditor.Editor editor, UnityEditor.UIElements.InspectorElement+DefaultInspectorFramework defaultInspectorFramework) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:317)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.Editor editor, UnityEditor.UIElements.InspectorElement+DefaultInspectorFramework defaultInspectorFramework) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:269)
UnityEditor.UIElements.InspectorElement..ctor (UnityEditor.Editor editor) (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/InspectorElement.cs:265)
UnityEditor.UIElements.EditorElement.BuildInspectorElement () (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/EditorElement.cs:171)
UnityEditor.UIElements.EditorElement.CreateInspectorElement () (at /Users/bokken/build/output/unity/unity/Editor/Mono/UIElements/Inspector/EditorElement.cs:286)
UnityEditor.EditorElementUpdater.CreateInspectorElementsForViewport (UnityEngine.UIElements.ScrollView viewport, UnityEngine.UIElements.VisualElement contentContainer) (at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/EditorElementUpdater.cs:99)
UnityEditor.PropertyEditor.RebuildContentsContainers () (at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/PropertyEditor.cs:1115)
UnityEditor.PropertyEditor.OnGUI () (at /Users/bokken/build/output/unity/unity/Editor/Mono/Inspector/PropertyEditor.cs:420)
UnityEditor.HostView.InvokeOnGUI (UnityEngine.Rect onGUIPosition) (at /Users/bokken/build/output/unity/unity/Editor/Mono/HostView.cs:512)
UnityEditor.DockArea.DrawView (UnityEngine.Rect dockAreaRect) (at /Users/bokken/build/output/unity/unity/Editor/Mono/GUI/DockArea.cs:385)
UnityEditor.DockArea.OldOnGUI () (at /Users/bokken/build/output/unity/unity/Editor/Mono/GUI/DockArea.cs:376)
UnityEngine.UIElements.IMGUIContainer.DoOnGUI (UnityEngine.Event evt, UnityEngine.Matrix4x4 parentTransform, UnityEngine.Rect clippingRect, System.Boolean isComputingLayout, UnityEngine.Rect layoutSize, System.Action onGUIHandler, System.Boolean canAffectFocus) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Core/IMGUIContainer.cs:355)
UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr, Boolean&) (at /Users/bokken/build/output/unity/unity/Modules/IMGUI/GUIUtility.cs:190)

Steps to Reproduce

  1. Define a serializable base class with a private array or list field.
  2. Create a serializable derived class that inherits from this base class.
  3. Attempt to inspect a component with a field of the derived class in the Inspector.

Sample Code

using UnityEngine;

namespace Alchemy.Samples
{
    public class InheritSample : MonoBehaviour
    {
        public DerivedClass derivedClass;

        [System.Serializable]
        public class BaseClass
        {
            [SerializeField]
            private float[] privateArray;
        }

        [System.Serializable]
        public class DerivedClass : BaseClass
        {
        }
    }
}
yuyu0127 commented 7 months ago

I fixed in https://github.com/AnnulusGames/Alchemy/pull/65