Единство EditorWindow # Фокус не может вызвать EditorWindow # OnGUI - PullRequest
0 голосов
/ 13 октября 2018

вот мой код:

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");
        }
    }
}

см. Мои гифки, когда я нажимаю на свой выигрыш и нажимаю ярлык "Ctrl + G", консоль выводит "запустить фокус" и "клавиша нажата" enter image description here

, но если я нажму на другой выигрыш (чтобы мой выигрыш потерял фокус) и нажму комбинацию клавиш «ctrl + g», чтобы сфокусировать выигрыш, консоль выведет только «запустить фокус», «ключнажатие "в OnGUI не может быть вызвано enter image description here, так как сконцентрировать EditorWindow в скрипте, чтобы заставить OnGUI работать после фокусировки

Ответы [ 2 ]

0 голосов
/ 13 октября 2018

Ваш текущий код должен работать.Протестировал его на моей стороне и он работал нормально.Я просто предположу, что это ошибка в редакторе.

Обходной путь для обнаружения нажатия клавиши, даже когда окно не сфокусировано, заключается в использовании подписки на событие EditorApplication.globalEventHandler.К сожалению, эта функция помечена как internal, поэтому вы не можете получить к ней доступ напрямую, но можете использовать отражение для доступа к ней.Это должно работать на любой платформе, которая поддерживает редактор.

В приведенном ниже примере вы получите журнал при нажатии Ctrl + G .

public class RoEditorWindow : EditorWindow
{
    private static RoEditorWindow win;
    EditorApplication.CallbackFunction appCb;

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

            Debug.Log("Run focus");
            win.Focus();
        }
    }

    void OnEnable()
    {
        EnableInputEvent();
    }

    void OnDisable()
    {
        DisableInputEvent();
    }

    void EnableInputEvent()
    {
        FieldInfo fieldInfo = typeof(EditorApplication).GetField("globalEventHandler", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
        appCb = (EditorApplication.CallbackFunction)fieldInfo.GetValue(null);
        appCb += OnEditorKeyPress;
        fieldInfo.SetValue(null, appCb);
    }

    void DisableInputEvent()
    {
        FieldInfo fieldInfo = typeof(EditorApplication).GetField("globalEventHandler", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
        appCb -= OnEditorKeyPress;
        fieldInfo.SetValue(null, appCb);
    }
    private void OnEditorKeyPress()
    {
        var ev = Event.current;
        if (ev.control && ev.type == EventType.KeyDown && ev.keyCode == KeyCode.G)
        {
            Debug.Log("key is pressed");
        }
    }
}
0 голосов
/ 13 октября 2018

эта проблема связана с тем, что я фокусирую плавающее окно редактора, если я перетаскиваю свой выигрыш, делаю его как tab редакторское окно (см. Мой gif), EditorWindow # Фокус работает хорошо

enter image description here

, если я действительно хочу использовать плавающий выигрыш

, вот мое решение, используйте EditorWindow # ShowAuxWindow и EditorWindow # titleContent, чтобы создать окно редактора с заголовком, включающим текущийРедактор единства проекта Идентификатор процесса

и использование кода окна фокуса os для фокусирования этого выигрыша, в Linux я могу использовать xdotool, в Windows, я думаю, что win32 api может это сделать, я думаю, что Mac имеет аналогичный способ

Вот мой редактор Unity для решения 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");
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...