Unity EditorWindow.Show 根本不工作

问题描述

平台:Unity 2020.3.9f1,Windows 64 位

我正在尝试制作一个自定义 EditorWindow,它应该响应组件上的上下文菜单操作而显示。但是,我无法显示它。当我尝试...没有任何反应。什么都没有。

代码

using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
public class TelnetConfigDialog : EditorWindow {

    private const int Margin = 10;
    private const float Spacing = 15;
    private static GUIStyle marginStyle;

    //[InitializeOnLoadMethod] static void InitTelnetConfigDialog () {   // no difference
    static TelnetConfigDialog () {
        Debug.Log("Initializing");
        DebugRemoteController.OnShowTelnetConfigDialog = () => {
            //Getwindow<TelnetConfigDialog>(true,"Configure Telnet Command",true).LogThenShow();   // no difference
            GetwindowWithRect<TelnetConfigDialog>(new Rect(0,200,200),true,true).LogThenShow();
        };
    }

    private string command;
    private string args;

    private void LogThenShow () {
        Debug.Log("Showing dialog...");
        //Show(true);      // does nothing
        //Show(false);     // does nothing
        //ShowModal();     // does nothing (doesn't block main window inputs either)
        //ShowUtility();   // does nothing
        Show();
        Debug.Log(position);
        Debug.Log(JsonUtility.ToJson(this));
    }

    void OnEnable () {
        Debug.Log("OnEnable");
        marginStyle ??= new GUIStyle {
            margin = new RectOffset(Margin,Margin,Margin)
        };
    }

    void OnGUI () { // never called
        Debug.Log("OnGUI");
        EditorGUILayout.BeginVertical(marginStyle);
        GUILayout.Label("Configure External Telnet Command",EditorStyles.boldLabel);
        GUILayout.Space(Spacing);
        command = EditorGUILayout.TextField("Executable",command);
        args = EditorGUILayout.TextField("Parameters",args);
        GUILayout.Space(Spacing);
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("",GUILayout.ExpandWidth(true));
        if (GUILayout.Button("OK",GUILayout.ExpandWidth(true))) Close();
        if (GUILayout.Button("Cancel",GUILayout.ExpandWidth(true))) Close();
        GUILayout.Label("",GUILayout.ExpandWidth(true));
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndVertical();
    }

}

静态初始值设定项将 LogThenShow 挂接到在别处组件的上下文菜单处理程序中调用的委托:

#if UNITY_EDITOR
    public delegate void ShowTelnetConfigDialog ();
    public static ShowTelnetConfigDialog OnShowTelnetConfigDialog;
    [ContextMenu("Configure Telnet Command...")]
    public void ConfigureTelnet () {
        OnShowTelnetConfigDialog();
    }
#endif

enter image description here

我可以确认它正在工作,因为我每次选择菜单时都会看到日志消息。但是:

  • 窗口不显示
  • 焦点不会改变(例如主窗口不会失去焦点等)
  • OnGUI 永远不会被调用(消息永远不会出现在日志中)
  • 只是为了确认:
    • 它似乎没有停靠在任何地方(我尽我所能地看着)。
    • 我在主编辑器窗口后面看了看,它不在那里。
    • 它的标题不在任务栏中(不知道是否应该在)。
    • 它不在 AltTabWinTab 列表中。
    • 它不在另一个桌面上(我没有打开)。
    • 它不在另一台显示器上(不存在)。

我尝试过的东西在上面代码的注释中被标记包括

  • 静态初始值设定项与 [InitOnLoad] 方法 -- 没有区别。
  • GetwindowWithRect vs Getwindow -- 没有区别。
  • 各种风格的 Show() -- 没有区别。
  • 省略我的自定义 marginStyle 样式 -- 没有任何区别。
  • 完全重新启动编辑器并重试 -- 没有任何区别。
  • 重新启动我的电脑(笑)-- 没有什么区别。
  • 奉承——没什么区别。
  • 口头威胁 -- 没有影响。
  • 为口头威胁道歉 - 没有任何区别。

我还注意到了一些看似奇怪的事情。考虑这个屏幕截图:

enter image description here

特别是:

  • 确实出现在窗口 -> 面板菜单中。
    • 在那里选择它没有任何作用。
    • 即使我完全重新启动编辑器并且从不单击上下文菜单,它也会出现在那里(这很奇怪吗?)。
  • 它被初始化,然后启用,然后 Show()调用,但 OnGUI() 从未发生。
  • 它认为它是 320 x 550,放在 (0,0) 处。不过,这绝对不是。
    • 即使我执行 GetwindowWithRect 并传递它(0,200),它仍然认为它是 (0,320,550)。

所以..... 假设 EditorWindows 应该可以工作(对吗?),我一定遗漏了一些东西,但我无法弄清楚它是什么。这一定是一些愚蠢的事情,但我已经没有想法了,现在是凌晨 5 点,几个小时以来,我一直在为这个相对不重要的代码浪费时间。我想我一直在关注文档示例,但我不知道。

在这里遗漏了什么?

解决方法

适用于我的机器 Unity 2020.3.10f1。视窗电脑。

enter image description here

(完全复制了您的两个代码片段 - 除了重新使用我现有的脚本 TEST 而不是 DebugRemoteController


这个位置对我来说听起来像是一个“错误”(没有详细记录的“功能”)->它只在那个时候使用给定的 Rect,如果从不是一个窗口输入 open 到目前为止。一旦您打开并移动它,Unity 就会存储该窗口类型的最后一个窗口矩形并重新使用该矩形。

如果您真的想确定可以直接覆盖 position


此外,您描述的主菜单阻塞听起来像是您想要使用 ShowModalShowModalUtility .. 老实说,我不明白这两者之间的区别 ^^。>

但是,老实说,我真的不明白这些应该如何被起诉,因为我刚刚尝试过,你得到的只是一个白色的窗口,直到你关闭它,因为它没有'在打开时不要对编辑器进行任何重绘:'D


一般来说,为什么要通过 OnShowTelnetConfigDialog 事件而不直接调用 TelnetConfigDialog.Open 之类的方法或类似的方法?或者例如使用

public static void LogThenShow() 
{
    Debug.Log("Showing dialog...");

    var window = GetWindowWithRect<TelnetConfigDialog>(new Rect(0,200,200),true,"Configure Telnet Command",true);
   
    window.Show();
    Debug.Log(window.position);
    Debug.Log(JsonUtility.ToJson(window));
}

以及你的行为

#if UNITY_EDITOR
    [ContextMenu("Configure Telnet Command...")]
    public void ConfigureTelnet () {
        TelnetConfigDialog.LogThenShow();
    }
#endif