Search code examples
c#unity-game-engineunity-editor

Serialized list erase content when changing focus on Unity custom EditorWindow


I've a custom unity editor window that displays a list of this type of objects:

[Serializable]
public class CustomAdditionalData
{
    public string PayloadKey;
    public string PayloadValue;
}

The list is correctly displayed, but when I type on any of the fields, if I change the focus to another field, it erase the content of the previous one, this is how I build the editor window:

#if UNITY_EDITOR
using System;
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;

namespace Tiles
{
    public class CustomEditorWindow : EditorWindow
    {
        [SerializeField]
        private List<CustomAdditionalData> payloadList = new List<CustomAdditionalData>();
        
        [MenuItem("Tools/Custom Window")]
        public static void ShowWindow()
        {
            var desiredDockWindow = Type.GetType("UnityEditor.InspectorWindow,UnityEditor.dll");
            GetWindow<CustomEditorWindow>("Custom Window", true, desiredDockWindow).Show();
        }
        
        private void OnGUI()
        {
            ScriptableObject target = this;
            var so = new SerializedObject(target);
            var payloadListProperty = so.FindProperty(nameof(payloadList));
            EditorGUILayout.PropertyField(payloadListProperty, true);
            so.ApplyModifiedProperties();
            EditorUtility.SetDirty(target); //I also tried without setting target to dirty, it does the same :(

            EditorGUILayout.Space();
            if (GUILayout.Button("Simulate")) {
                SimulateButton();
            }
        }

        private void SimulateButton()
        {
            var payloadDict = payloadList.ToDictionary<CustomAdditionalData, string, object>(payloadAdditionalData => payloadAdditionalData.PayloadKey, payloadAdditionalData => payloadAdditionalData.PayloadValue);
            //Do something with the payloadDict
        }
    }
}
#endif

Solution

  • OnGUI() method is called very often, not only once (you can find an explanation here). And you are creating a new instance of ScriptableObject in every call.

    It looks like it just cannot have a chance to be saved. You should create the object you want to edit only once. For example, in your ShowWindow method.