AnnulusGames / Alchemy

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

Nested Lists of Lists of Lists are leading to NullReferenceException when pressing "+" in the Inspector #87

Open max-critcrew opened 2 months ago

max-critcrew commented 2 months ago

Hey,

first of all - we love Alchemy and this is our first issue we're encountering. So we wanted to report it, to see if anyone has a fix already.

Unity Version: 2022.3.17f1 Alchemy Version: 2.0.1

Example reproduction code file:

using System.Collections;
using System.Collections.Generic;
using Alchemy.Inspector;
using UnityEngine;

[Serializable]
public class ContainerClass
{
    [SerializeField] public List<int> listOfInt = new List<int>();

}

[Serializable]
public class SecondContainerClass
{
    [SerializeField] public List<ContainerClass> listOfContainerClass = new List<ContainerClass>();

}

public class MyTest : MonoBehaviour
{
    [SerializeField] public List<SecondContainerClass> listOfListOfList = new List<SecondContainerClass>();

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }
}

Simply add this to any GameObject and press plus in the nested lists:

image

Error in screenshot:

image

Error as text:

NullReferenceException: Object reference not set to an instance of an object
Alchemy.Editor.Elements.PropertyListView+<>c__DisplayClass0_2.<.ctor>b__2 (UnityEditor.SerializedProperty x) (at ./Library/PackageCache/com.annulusgames.alchemy@b03898d42a/Editor/Elements/PropertyListView.cs:32)
UnityEditor.UIElements.Bindings.DefaultSerializedObjectBindingImplementation+<>c__DisplayClass7_0.<TrackPropertyValue>b__0 (System.Object e, UnityEditor.SerializedProperty p) (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:1010)
UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.UpdateTrackedProperties () (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/Bindings/BindingExtensions.cs:844)
UnityEditor.RetainedMode:UpdateSchedulers() (at /Users/bokken/build/output/unity/unity/ModuleOverrides/com.unity.ui/Editor/RetainedMode.cs:55)

Thanks for your time looking at this and if you got any input or ideas, let us know :)

max-critcrew commented 1 month ago

@AnnulusGames Heya! I hope it's okay if I ping you here! I was wondering if you got any idea what this might be caused by. Otherwise, I might have a look son how/if I can fix this.

smile12yen commented 1 month ago

Same problem. I suspected the problem was due to the language used, but it seems to occur in all languages. (I use Japanese for UnityEditor).

Unity Version: 2022.3.10f1 Alchemy Version: 2.0.1

smile12yen commented 1 month ago

A temporary solution is to add an [OnListViewChanged] attribute to the main double-nested list to ignore the error. For example, a ScriptableObject written as follows will not raise an error

public class Test : ScriptableObject
{
    [OnListViewChanged]
    public List<DummyData> craftLineupList = new List<CraftLineup>();
}

[System.Serializable]
public class DummyData
{
    public List<string> craftLineupItemNames = new List<string>();
}
max-critcrew commented 1 month ago

@smile12yen thanks so much, this is some good news! Do you have any idea if this causes any possible side effects? :)

smile12yen commented 1 month ago

@max-critcrew It works temporarily, but I don't know what side effects it has for me. Adding this attribute seems to solve the problem by allowing event handling when a list is added or removed, but the attribute should normally be added automatically from the editor script. (This attribute itself is contained in Alchemy.Inspector.) I will try this method for a while and will report any side effects.

max-critcrew commented 1 month ago

Thank you! In case it helps it also works to disable the AlchemyEditor for this class with [DisableAlchemyEditor] It somewhat defeats the purpose of using Alchemy of course :)