You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity自定义EditorWindow切换焦点时列表内容被清除问题求助

问题原因

字段内容切换焦点后丢失的核心原因是每次OnGUI调用时都重新创建SerializedObject实例,导致输入的修改还未同步到窗口的序列化数据中,就被新实例读取的原始数据覆盖。另外,EditorUtility.SetDirty在这里属于多余操作,甚至可能干扰序列化流程。

解决方案

修改编辑器窗口代码,缓存SerializedObject实例,并在OnGUI中正确执行数据同步流程:

  1. 声明类级别的SerializedObject变量缓存实例
  2. 在OnEnable方法中初始化该实例
  3. 在OnGUI开头调用so.Update()读取最新窗口数据
  4. 移除不必要的EditorUtility.SetDirty调用

修改后的完整代码:

#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>();
        
        // 缓存SerializedObject实例
        private SerializedObject so;

        [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 OnEnable()
        {
            // 初始化SerializedObject
            so = new SerializedObject(this);
        }
        
        private void OnGUI()
        {
            // 读取最新的窗口数据到SerializedObject
            so.Update();
            
            var payloadListProperty = so.FindProperty(nameof(payloadList));
            EditorGUILayout.PropertyField(payloadListProperty, true);
            
            // 将修改同步回窗口的序列化数据
            so.ApplyModifiedProperties();

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

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

    [Serializable]
    public class CustomAdditionalData
    {
        public string PayloadKey;
        public string PayloadValue;
    }
}
#endif
额外说明
  • 将CustomAdditionalData类移入命名空间内,避免序列化时出现类型不可访问的潜在问题
  • SerializedObject.Update()负责从窗口实例读取最新数据,ApplyModifiedProperties()负责将修改写回窗口实例,两者配合确保数据正确同步
  • 新版Unity中EditorUtility.SetDirty已标记为过时,针对ScriptableObject(包括EditorWindow),使用SerializedObject的同步方法或Undo.RecordObject处理修改即可

内容的提问来源于stack exchange,提问作者Lotan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:43:18