如何通过UIToolkit监听IMGUIContainer中的内容变更?
监听InspectorElement中IMGUIContainer的变更
你的问题出在覆盖onGUIHandler时没有保留原有的Inspector绘制逻辑,而且变更检查的时机不对。以下是两种可行的解决方案:
方案一:包裹原有IMGUI绘制逻辑
先保存原来的onGUIHandler,再在自定义逻辑中包裹变更检查,同时执行原绘制代码:
// 保存原有的IMGUI绘制逻辑 var originalOnGUI = _imguiLevelContainer.onGUIHandler; // 替换为包含变更检查的handler _imguiLevelContainer.onGUIHandler = () => { EditorGUI.BeginChangeCheck(); // 执行原有的Inspector绘制 originalOnGUI?.Invoke(); if (EditorGUI.EndChangeCheck()) { // 标记对象为已修改,确保Undo/Redo生效 EditorUtility.SetDirty(_selectedLevel); _levelListView.Rebuild(); Debug.Log("检测到变更"); } };
方案二:监听SerializedObject的变更
利用SerializedObject的特性,结合编辑器事件来捕获变更:
方法A:通过EditorApplication.update实时检查
private SerializedObject _levelSerializedObject; // 在绑定阶段保存SerializedObject _levelSerializedObject = new SerializedObject(_selectedLevel); _levelInspector.Bind(_levelSerializedObject); // 注册帧更新回调 EditorApplication.update += CheckLevelChanges; // 检查变更的逻辑 private void CheckLevelChanges() { if (_levelSerializedObject == null) return; _levelSerializedObject.Update(); if (_levelSerializedObject.hasChanged) { _levelSerializedObject.ApplyModifiedProperties(); _levelListView.Rebuild(); Debug.Log("检测到变更"); } } // 窗口关闭时移除回调,避免内存泄漏 private void OnDestroy() { EditorApplication.update -= CheckLevelChanges; }
方法B:监听Undo/Redo后的修改事件
这个事件会在所有对象修改操作(包括手动编辑、Undo/Redo)完成后触发:
private void OnEnable() { Undo.postprocessModifications += OnPostprocessModifications; } private void OnDisable() { Undo.postprocessModifications -= OnPostprocessModifications; } private UndoPropertyModification[] OnPostprocessModifications(UndoPropertyModification[] modifications) { foreach (var mod in modifications) { if (mod.currentValue.target == _selectedLevel) { _levelListView.Rebuild(); Debug.Log("检测到Level对象变更"); break; } } return modifications; }
注意事项:
- 必须使用
EditorUtility.SetDirty或SerializedObject.ApplyModifiedProperties确保修改被Unity识别,支持Undo/Redo功能。 - 所有注册的编辑器事件回调,要在窗口销毁/禁用时移除,避免内存泄漏。
内容的提问来源于stack exchange,提问作者matrosky
相关产品推荐
相关产品推荐

