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

Unity3D多Utility窗口问题:如何让子Utility窗口阻塞父窗口?

Unity模态Utility窗口阻塞父窗口的解决方案

Unity的ShowModalUtility()方法仅会阻塞主编辑器界面,不会自动禁用其他已打开的Utility窗口,所以需要手动控制父窗口的启用状态来实现阻塞效果。以下是具体的修改方案:

核心思路

  1. 打开子窗口时,将父窗口实例传递给子窗口
  2. 子窗口打开后立即禁用父窗口(enabled = false),使其无法交互
  3. 子窗口关闭时,恢复父窗口的启用状态

修改后的完整代码

using UnityEditor;
using UnityEngine;

public class Test
{
    public class TestWindow1 : EditorWindow
    {
        [MenuItem("TEST/Test Window 1")]
        public static void Open()
        {
            var window = GetWindow<TestWindow1>(true, "Test Window 1");
            window.ShowModalUtility();
        }

        private string text = "";

        void OnGUI()
        {
            text = EditorGUILayout.TextField("Try To Write Here:", text);
            if (GUILayout.Button("Open Test Window 2"))
            {
                // 打开子窗口时传入当前父窗口实例
                TestWindow2.Open(this);
            }
        }
    }

    public class TestWindow2 : EditorWindow
    {
        // 存储父窗口引用
        private EditorWindow parentWindow;

        // 修改Open方法,接收父窗口参数
        public static void Open(EditorWindow parent)
        {
            var window = GetWindow<TestWindow2>(true, "Test Window 2");
            // 传递父窗口引用
            window.parentWindow = parent;
            // 禁用父窗口
            parent.enabled = false;
            window.ShowModalUtility();
        }

        private string text = "";

        void OnGUI()
        {
            text = EditorGUILayout.TextField("Try To Write Here:", text);
            if (GUILayout.Button("Open Test Window 3"))
            {
                // 打开下一级子窗口时传入当前窗口作为父窗口
                TestWindow3.Open(this);
            }
        }

        // 窗口关闭时恢复父窗口状态
        private void OnDestroy()
        {
            if (parentWindow != null)
            {
                parentWindow.enabled = true;
            }
        }
    }

    public class TestWindow3 : EditorWindow
    {
        private EditorWindow parentWindow;

        public static void Open(EditorWindow parent)
        {
            var window = GetWindow<TestWindow3>(true, "Test Window 3");
            window.parentWindow = parent;
            parent.enabled = false;
            window.ShowModalUtility();
        }

        void OnGUI()
        {
            EditorGUILayout.LabelField("NOTHING TO DO HERE!!!!");
        }

        private void OnDestroy()
        {
            if (parentWindow != null)
            {
                parentWindow.enabled = true;
            }
        }
    }
}

代码说明

  • 每个子窗口类新增parentWindow字段,用于保存父窗口的引用
  • 修改Open方法,接收父窗口实例参数,打开子窗口前先禁用父窗口
  • 在子窗口的OnDestroy回调中,恢复父窗口的启用状态,确保子窗口关闭后父窗口能正常交互

这样修改后,打开TestWindow2时TestWindow1会被禁用无法操作,关闭TestWindow2后TestWindow1恢复可用;同理TestWindow3会阻塞TestWindow2,完全实现层级模态阻塞的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:45:32