这是我的代码:
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图像,当我单击我的获胜并按下快捷键“ ctrl + g”时,控制台将输出“运行焦点”并且“按下键”
但是如果我单击其他获胜(使我的获胜失去焦点)并按下快捷键“ ctrl + g”来获得获胜,则控制台仅输出“运行焦点”,无法在OnGUI中调用“按键” 那么如何在脚本中聚焦EditorWindow以便使聚焦后的OnGUI工作
答案 0 :(得分:1)
这个问题是因为我专注于浮动编辑器窗口,如果我拖动胜利,使其成为 tab editorwindow(请参见我的gif),EditorWindow#Focus效果很好
如果我真的想使用浮动赢奖
这是我的解决方案,使用EditorWindow#ShowAuxWindow和EditorWindow#titleContent创建标题为带有当前项目统一编辑器进程ID的editorwindow
并使用os focus窗口代码来聚焦此胜利,在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");
}
}
}
答案 1 :(得分:0)
您当前的代码应该可以使用。在我这边进行了测试,效果很好。我只是假设这是编辑器中的错误。
即使在窗口未聚焦时也可以检测按键的解决方法是使用订阅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");
}
}
}