使用EventSystem进行按键事件

时间:2018-05-22 15:14:07

标签: c# unity3d

上下文:说你要检查是否" W"按下键盘,最常见的检查方法是通过以下代码:

void Update(){
    if (Input.GetKeyDown("W"))
        DoSomething();
}

使用Unity的EventSystem有没有办法做到以下几点?换句话说,是否有像 IPointerClickHandler 这样的接口的实现,例如,检查按钮是否被按下,而不是在 Update()函数中这样做? / p>

2 个答案:

答案 0 :(得分:5)

  

有没有办法使用Unity的EventSystem执行以下操作?换句话说,是否有像IPointerClickHandler这样的接口的实现,

没有。 EventSystem主要用于光线投射和调度事件。这不用于检测键盘事件。 EventSystem中唯一可以检测键盘事件的组件是InputField组件。就是这样,它不能用于其他任何事情。

  

检查按钮是否被按下,而不是在Update()中按下   功能

是的,Event.KeyboardEvent有一种方式,这需要OnGUI功能。

void OnGUI()
{
    if (Event.current.Equals(Event.KeyboardEvent("W")))
    {
        print("W pressed!");
    }
}

这比使用Input.GetKeyDown函数的Update函数更糟糕。我鼓励你坚持使用Input.GetKeyDown。它没有任何问题。

如果您要查找没有Input.GetKeyDown的事件类型InputSystem,请使用Unity的新输入API并订阅InputSystem.onEvent事件。

如果您正在寻找与IPointerClickHandler界面类似的功能,则可以在Input.GetKeyDown之上实施。

1 。首先,使用KeyCode获取所有System.Enum.GetValues(typeof(KeyCode));枚举,并将其存储在数组中。

2 。创建一个“IKeyboardEvent”接口,并在OnKeyDown界面中添加OnPointerClickIPointerClickHandler等功能。

3 。点击#1 中的KeyCode,检查数组中的每个键是否被按下,释放或按下。

4 。获取场景中的所有组件,并检查它们是否实现了IKeyboardEvent界面。如果有,请根据#3 中的密钥状态在界面中调用正确的功能。

以下是一个仍可以扩展或改进的功能示例:

附加到空的GameObject。

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class KeyboardEventSystem : MonoBehaviour
{
    Array allKeyCodes;

    private static List<Transform> allTransforms = new List<Transform>();
    private static List<GameObject> rootGameObjects = new List<GameObject>();

    void Awake()
    {
        allKeyCodes = System.Enum.GetValues(typeof(KeyCode));
    }

    void Update()
    {
        //Loop over all the keycodes
        foreach (KeyCode tempKey in allKeyCodes)
        {
            //Send event to key down
            if (Input.GetKeyDown(tempKey))
                senEvent(tempKey, KeybrdEventType.keyDown);

            //Send event to key up
            if (Input.GetKeyUp(tempKey))
                senEvent(tempKey, KeybrdEventType.KeyUp);

            //Send event to while key is held down
            if (Input.GetKey(tempKey))
                senEvent(tempKey, KeybrdEventType.down);

        }
    }


    void senEvent(KeyCode keycode, KeybrdEventType evType)
    {
        GetAllRootObject();
        GetAllComponents();

        //Loop over all the interfaces and callthe appropriate function
        for (int i = 0; i < allTransforms.Count; i++)
        {
            GameObject obj = allTransforms[i].gameObject;

            //Invoke the appropriate interface function if not null
            IKeyboardEvent itfc = obj.GetComponent<IKeyboardEvent>();
            if (itfc != null)
            {
                if (evType == KeybrdEventType.keyDown)
                    itfc.OnKeyDown(keycode);
                if (evType == KeybrdEventType.KeyUp)
                    itfc.OnKeyUP(keycode);
                if (evType == KeybrdEventType.down)
                    itfc.OnKey(keycode);
            }
        }
    }

    private static void GetAllRootObject()
    {
        rootGameObjects.Clear();

        Scene activeScene = SceneManager.GetActiveScene();
        activeScene.GetRootGameObjects(rootGameObjects);
    }


    private static void GetAllComponents()
    {
        allTransforms.Clear();

        for (int i = 0; i < rootGameObjects.Count; ++i)
        {
            GameObject obj = rootGameObjects[i];

            //Get all child Transforms attached to this GameObject
            obj.GetComponentsInChildren<Transform>(true, allTransforms);
        }
    }

}

public enum KeybrdEventType
{
    keyDown,
    KeyUp,
    down
}

public interface IKeyboardEvent
{
    void OnKeyDown(KeyCode keycode);
    void OnKeyUP(KeyCode keycode);
    void OnKey(KeyCode keycode);
}

<强>用法

在脚本中实现IKeyboardEvent界面及其功能,就像使用IPointerClickHandler一样。

public class test : MonoBehaviour, IKeyboardEvent
{
    public void OnKey(KeyCode keycode)
    {
        Debug.Log("Key held down: " + keycode);
    }

    public void OnKeyDown(KeyCode keycode)
    {
        Debug.Log("Key pressed: " + keycode);
    }

    public void OnKeyUP(KeyCode keycode)
    {
        Debug.Log("Key released: " + keycode);
    }
}

答案 1 :(得分:1)

我创建了一个简单脚本来触发简单事件。 我用的是OnguiGUI而不是Update。 看到它了!

using UnityEngine;
using UnityEngine.Events;

public class TriggerKey : MonoBehaviour
{

    [Header("----Add key to trigger on pressed----")]
    public string key;

    // Unity event inspector
    public UnityEvent OnTriggerKey;

    public void OnGUI()
    {    // triiger event on trigger key
        if (Event.current.Equals(Event.KeyboardEvent(key)))
        {
            OnTriggerKey.Invoke();
            print("test trigger btn");
        }

    }
}