Insert new custom class element with _default_ values to a SerializedProperty array?

In a custom inspector, I am adding a new custom class “DSReaction” element to a native array named “reactions” obtained via a SerializedProperty. To add the new element to the “reactions” array, I’m using the “InsertArrayElementAtIndex” function.

Here is a stripped-down version of the code:

using UnityEditor;

[CustomEditor(typeof(DSReacter))]
public class DSReacterEditor : Editor
{
	private DSReacter T;
	private SerializedObject Reactor;
		
	private SerializedProperty reactions;

    private void OnEnable()
    {
		T = target as DSReacter;
    
		Reactor = new SerializedObject(T);
			
		reactions = Reactor.FindProperty("reactions");
	}
		
	public override void OnInspectorGUI()
    {
        Reactor.UpdateIfDirtyOrScript();
        
	    if (GUILayout.Button("New Reaction"))
		reactions.InsertArrayElementAtIndex(0);
				
		Reactor.ApplyModifiedProperties();
	}
}

Unfortunately, if the array is not empty, this automatically creates the new element using the variable valuables of the preceding element.

How can I add a new element, but have it retain the default class variable values, as opposed to the values of the preceding element?

Thank you in advance, and be well!

- S.

1 Answer

1

That’s not possible using SerializedObject / Property. “InsertArrayElementAtIndex” works the same way as the default inspector. When you change the “size” of an array the new values at the end are initialized with the last element in the array. The serialization system doesn’t seem to offer a way to initialize an object instance with default values.

The only alternative would be to access the target object manually and modify the array yourself.

Since you already use the target property you should be able to do the following. Note since you did not provide your “DSReacter” class nor your custom data class i can only assume that the “reactions” variable is a native array:

if (GUILayout.Button("New Reaction"))
{
    Undo.RecordObject(T, "Added Reaction");
    var list = new List<YourCustomClass>(T.reactions);
    list.Add(new YourCustomClass());
    T.reactions = list.ToArray();
}

Note the Undo.RecordObject is required or the editor won’t detect the changes.

@Bunny83: Yes, you assumed correctly that T.reactions is a native array. I had presumed that I was overlooking a method offered by SerializedProperty. Glad to know that it was the lack of a method as opposed to my inability to locate one. Thank you for your response and example. I've tested it, and it works perfectly. Additionally, I've updated my original post to clarify it for future reads based on your comment. Thank you again, and be well! \- S.

Wouldn't it be possible to do something like reactions.InsertArrayElementAtIndex(0); reactions.GetArrayElementAtIndex(0).objectReferenceValue = new Reaction(); instead?