首页 > 解决方案 > unity EditorWindow#Focus 无法触发 EditorWindow#OnGUI

问题描述

这是我的代码:

public class RoEditorWindow : EditorWindow
{
    private static RoEditorWindow win;

    [MenuItem("Window/Ro Editor Window %g")]
    static void St()
    {
        if (!win)
        {
            win = EditorWindow.GetWindow<RoEditorWindow>();
        }
        else
        {
            Debug.Log("Run focus");
            win.Focus();
        }
    }

    private void OnGUI()
    {
        var ev = Event.current;
        if (ev.isKey )
        {
            Debug.Log("key is pressed");
        }
    }
}

查看我的 gif,当我点击我的 win 并点击快捷键“ctrl+g”时,控制台将输出“运行焦点”和“按键被按下” 在此处输入图像描述

但是如果我点击其他win(让我的win失去焦点)并点击快捷键“ctrl+g”来关注win,控制台只输出“运行焦点”,无法调用OnGUI中的“key ispressed”在此处输入图像描述 所以​​如何在EditorWindow中聚焦聚焦后使 OnGUI 工作的脚本

标签: c#unity3d

解决方案


这个问题是因为我关注浮动编辑器窗口,如果我拖动我的胜利使其成为标签编辑器窗口(见我的 gif),EditorWindow#Focus 工作得很好

在此处输入图像描述

如果我真的想使用浮动获胜

这是我的解决方案,使用 EditorWindow#ShowAuxWindow 和 EditorWindow#titleContent 创建包含当前项目统一编辑器进程 ID 的标题的编辑器窗口

并使用os focus window code来关注这个win,在linux中我可以使用xdotool,在windows中,我猜win32 api可以做到,我认为mac有类似的方式

这是我用于 linux 解决方案的统一编辑器:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;

public class RoEditorWindow : EditorWindow
{
    private static RoEditorWindow win;

    [MenuItem("Window/Ro Editor Window %g")]
    static void St()
    {
        if (!win)
        {
            win = ScriptableObject.CreateInstance<RoEditorWindow>();
        }

        Debug.Log("Run Focus");
        win.ShowAuxWindow();
        EditorWindow.FocusWindowIfItsOpen<RoEditorWindow>();
        var title = $"Ro Editor Windows in Process {Process.GetCurrentProcess().Id}";
        win.SetTitle(title);
        new Thread(() =>
        {
            var startAt = DateTime.Now;
            while (true)
            {
                try
                {
                    var cmd = $"xdotool search --name --onlyvisible --limit  1 \"{title}\"";
                    var wid = Sh(cmd);
                    if (wid != "")
                    {
                        Sh($"xdotool windowactivate {wid}");
                        break;
                    }
                }
                catch (SystemException e)
                {
                }

                if ((DateTime.Now - startAt).TotalSeconds > 5)
                {
                    break;
                }
            }
        }).Start();
    }

    public static string Sh(string cmd)
    {
        string output = "";
        string error = string.Empty;

        var psi = new ProcessStartInfo("/bin/bash", $"-c '{cmd}'");

        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;
        psi.UseShellExecute = false;
        Process p = Process.Start(psi);
        using (System.IO.StreamReader myOutput = p.StandardOutput)
        {
            output = myOutput.ReadToEnd();
        }

        using (System.IO.StreamReader myError = p.StandardError)
        {
            error = myError.ReadToEnd();
        }

        if (error != "")
        {
            throw new SystemException($"err cmd: {cmd}\n{error}");
        }

        return output;
    }


    public void SetTitle(string v)
    {
        titleContent = new GUIContent(v);
    }

    private void OnGUI()
    {
        EditorGUILayout.TextField("input", "");
        if (Event.current.isKey)
        {
            Debug.Log("key is pressed");
        }
    }
}

推荐阅读