How to call a method on creation of new list elements within the Editor

I have a class, let’s call it MyClass.

I also have a ScriptableObject, let’s call it MyScriptableObject, that contains a List.

I create a MyScriptableObject asset and open it. This shows an empty list in the inspector.

In the inspector I set the size of the list to, say 4, and it shows me 4 elements, each with default values.

Is there a way I can get it to run a particular method at the point those elements are created?

In my case, MyClass has a Guid field and I want to set it to Guid.NewGuid() when the element is created so that every new instance has its own unique ID.

The parameterless constructor runs whenever the object is created or deserialized. As far as I remember. But be careful it may run multiple times in editor. And test it before you rely on it in build.
So just add a MyClass constructor to your class.

I was wondering if there is a way I can catch the moment an element is first created in the editor (or when it is first renderered) using a custom editor, but I don’t have enough experience with custom editors to answer this question myself.

“I was wondering if there is a way I can catch the moment an element is first created in the editor (or when it is first renderered) using a custom editor”

I don’t know if there is a way to detect new elements, but couldn’t you use EditorGUI.BeginChangeCheck?

Draw your list in between Begin and EndChangeCheck.

If there is a change, check your list and see which element is new and do required things, like check if the element guid is not set.

I found that using the parameterless constructor didn’t work. The editor must be overwriting contents of the new element (deserializing) after calling the constructor.

I’d like to understand the process going on within the editor, so I’ve asked this question .

I ended up asking a more specific question on the forum , and got a solution, which is essentially: use OnValidate() to check the list. Obviously this happens after the editor has created and populated the new element, but it does at least give me a way of checking and fixing any data.

I know you’ve asked another question, but anyway, this is what I’ve done… I use the serialized object and draw the list between Begin and End ChangeCheck. This was good enough for me IIRC, I know this probably isn’t what you are looking for, but it might be useful for someone else.

Some MB with a list:

public class TestList : MonoBehaviour
{
    public List<string> list;
}

Editor for MB in question. Will print debug log when list is added/removed or modified:

[CustomEditor(typeof(TestList))]
public class TestListEditor : Editor
{
    SerializedProperty list;

    void OnEnable() =>
        list = serializedObject.FindProperty("list");

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        EditorGUI.BeginChangeCheck();

        // list rendered here
        EditorGUILayout.PropertyField(list);

        // end change check
        if (EditorGUI.EndChangeCheck())
            Debug.Log("list size now:" + list.arraySize.ToString());

        serializedObject.ApplyModifiedProperties();
    }
}
1 Like