Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在inspector中获取当前按下的键_C#_Unity3d_Unity3d Editor - Fatal编程技术网

C# 在inspector中获取当前按下的键

C# 在inspector中获取当前按下的键,c#,unity3d,unity3d-editor,C#,Unity3d,Unity3d Editor,我目前正在为我的Unity项目构建一个简单的快捷方式系统 目前,我正在通过字符串在inspector中插入快捷方式,例如:Control+Alt+A。但是每次编写它都太烦人了 因此,我考虑为它创建一个自定义编辑器,其中文本框将自动填充用户按下的键。不幸的是,我发现获取此信息的唯一方法是使用OnSceneGUI函数,但它要求场景窗口具有焦点,如果在Unity中定义了快捷方式,则会触发 总之,我如何读取当前按下的键并用编辑器脚本显示它们 编辑:几乎可以满足我的需要,但它只检测到一个键,没有组合,而且

我目前正在为我的Unity项目构建一个简单的快捷方式系统

目前,我正在通过字符串在inspector中插入快捷方式,例如:Control+Alt+A。但是每次编写它都太烦人了

因此,我考虑为它创建一个自定义编辑器,其中文本框将自动填充用户按下的键。不幸的是,我发现获取此信息的唯一方法是使用OnSceneGUI函数,但它要求场景窗口具有焦点,如果在Unity中定义了快捷方式,则会触发

总之,我如何读取当前按下的键并用编辑器脚本显示它们


编辑:几乎可以满足我的需要,但它只检测到一个键,没有组合,而且根本检测不到Shift键

很大程度上取决于您以后如何存储和检查热键,但您可以创建自定义的EditorWindow弹出窗口

首先,我会存储我的快捷方式,例如

[Serializable]
public struct ShortCut
{
    public bool Ctrl;
    public bool Alt;
    public bool Shift;

    public KeyCode Key;

    public ShortCut(KeyCode key, bool ctrl, bool alt, bool shift)
    {
        Key = key;
        Ctrl = ctrl;
        Alt = alt;
        Shift = shift;
    }

    public override string ToString()
    {
        var builder = new StringBuilder();
        if (Ctrl) builder.Append("CTRL + ");
        if (Alt) builder.Append("ALT + ");
        if (Shift) builder.Append("SHIFT + ");

        builder.Append(Key.ToString());

        return builder.ToString();
    }

    public bool IsDown => IsCtrlDown && IsAltDown && IsShiftDown && Input.GetKeyDown(Key);

    private bool IsCtrlDown => !Ctrl || Input.GetKey(KeyCode.RightControl) || Input.GetKey(KeyCode.LeftControl);
    private bool IsAltDown => !Alt || Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
    private bool IsShiftDown => !Shift || Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
}
您可以在脚本中等待它,例如

public class ShortCutTester : MonoBehaviour
{
    // This youc an now call via the context menu of the someShortCut field in the Inspector
    [ContextMenuItem("Set Shortcut", nameof(SetSomeShortCut))]
    public ShortCut someShortCut;

    private void SetSomeShortCut()
    {
        ShortKeyDialog.ShowDialog(someShortCut, result =>
        {
            // mark as dirty and provide undo/redo funcztionality
            Undo.RecordObject(this, "Change someShortCut");
            someShortCut = result;
        });
    }

    private void Update()
    {
        if (someShortCut.IsDown)
        {
            Debug.Log("Hello!");
        }
    }

    #if UNITY_EDITOR
    // in order to catch all editor own key events on runtime
    // you will still get the warning "You have to exit playmode in order to save"
    // but at least this makes the Hello print anyway. Couldn't figure out how to catch the key completely before Unity handles it
    private void OnGUI()
    {
        var e = Event.current;
        e.Use();
    }
    #endif
}
并通过弹出对话框进行设置

public class ShortKeyDialog : EditorWindow
{
    private ShortCut keys;
    private ShortCut newKeys;
    private Action<ShortCut> callback;
    private bool changed;

    public static void ShowDialog( ShortCut currentShortcut, Action<ShortCut> onDone)
    {
        var dialog = GetWindow<ShortKeyDialog>();
        dialog.keys = currentShortcut;
        dialog.newKeys = currentShortcut;
        dialog.callback = onDone;
        dialog.minSize = new Vector2(300, 200);
        dialog.position = new Rect(Screen.width / 2f + 150, Screen.height / 2f + 100, 300, 200);
        dialog.ShowModalUtility();
    }

    private void OnGUI()
    {
        //Get pressed keys
        var e = Event.current;
        if (e?.isKey == true)
        {
            switch (e.type)
            {
                case EventType.KeyDown:
                    switch (e.keyCode)
                    {
                        // Here you will need all allowed keycodes
                        case KeyCode.A:
                        case KeyCode.B:
                        case KeyCode.C:
                        case KeyCode.D:
                        case KeyCode.E:
                        case KeyCode.F:
                        case KeyCode.G:
                        case KeyCode.H:
                        case KeyCode.I:
                        case KeyCode.J:
                        case KeyCode.K:
                        case KeyCode.L:
                        case KeyCode.M:
                        case KeyCode.N:
                        case KeyCode.O:
                        case KeyCode.P:
                        case KeyCode.Q:
                        case KeyCode.R:
                        case KeyCode.S:
                        case KeyCode.T:
                        case KeyCode.U:
                        case KeyCode.V:
                        case KeyCode.W:
                        case KeyCode.X:
                        case KeyCode.Y:
                        case KeyCode.Z:
                        case KeyCode.F1:
                        case KeyCode.F2:
                        case KeyCode.F3:
                        case KeyCode.F4:
                        case KeyCode.F5:
                        case KeyCode.F6:
                        case KeyCode.F7:
                        case KeyCode.F8:
                        case KeyCode.F9:
                        case KeyCode.F10:
                        case KeyCode.F11:
                        case KeyCode.F12:
                        case KeyCode.F13:
                        case KeyCode.F14:
                        case KeyCode.F15:
                        case KeyCode.Comma:
                        case KeyCode.Plus:
                        case KeyCode.Minus:
                        case KeyCode.Period:
                            // etc depends on your needs I guess
                            changed = true;
                            newKeys = new ShortCut (e.keyCode, e.control, e.alt, e.shift);

                            // Refresh the EditorWindow
                            Repaint();
                            break;
                    }
                    break;
            }

            // Use all key presses so nothing else handles them 
            // e.g. also not the Unity editor itself like e.g. for CTRL + S
            e.Use();
        }

        EditorGUILayout.LabelField("Current Shortcut");
        EditorGUILayout.HelpBox(keys.ToString(), MessageType.None);

        EditorGUILayout.Space();

        EditorGUILayout.LabelField("Press buttons to assign a new shortcut", EditorStyles.textArea);

        EditorGUILayout.HelpBox(newKeys.ToString(), MessageType.None);

        EditorGUILayout.Space();

        EditorGUILayout.BeginHorizontal();
        {
            if (GUILayout.Button("Cancel"))
            {
                Close();
            }
            EditorGUI.BeginDisabledGroup(!changed);
            {
                if (GUILayout.Button("Save"))
                {
                    callback?.Invoke(newKeys);
                    Close();
                }
            }
            EditorGUI.EndDisabledGroup();
        }
        EditorGUILayout.EndHorizontal();
    }
}
请注意:在智能手机上打字,所以目前没有机会测试和纠正问题,但我希望想法变得清晰


回到电脑上后会尽快测试和更新

@BugFinder不是我需要的它工作正常,但我有两个问题;1什么是dialog.ShowModalUtility,它不编译。2有没有办法取消Unity中的快捷键呢?因为像Ctrl+S这样的快捷键也与Unity有关。请注意,我已经用我在问题中链接的脚本修复了这些问题。我会尽快更新我的问题,以包含正确和完整的代码。非常感谢你,你总是给出最好和最详细的回答,我刚刚修正了所有的打字错误和东西;现在再试一次工作正常,但dialog.ShowModalUtility仍无法编译.p.s。如果我想要一个快捷方式列表而不仅仅是一个,它还能工作吗