使用EventSystem进行按键事件 [英] Use EventSystem for key-pressing events
问题描述
上下文:说您正在检查是否在键盘上按下了"W",最常见的检查方法是通过以下代码:
Context: say you're checking whether "W" is pressed on the keyboard, the most common way to check this is through the following code:
void Update(){
if (Input.GetKeyDown("W"))
DoSomething();
}
是否可以使用Unity的EventSystem执行以下操作?换句话说,是否存在例如 IPointerClickHandler 之类的接口的实现,以检查是否按下了按钮,而没有在 Update()函数中这样做?/p>
Is there a way to do the following, using Unity's EventSystem? In other words, is there an implementation of an interface like IPointerClickHandler, for example, to check whether a button is pressed, without doing so in an Update() function?
推荐答案
是否可以使用Unity的EventSystem执行以下操作?换句话说,是否有IPointerClickHandler之类的接口的实现,
Is there a way to do the following, using Unity's EventSystem? In other words, is there an implementation of an interface like IPointerClickHandler,
不. EventSystem主要用于光线广播和调度事件.这不用于检测键盘事件. EventSystem中唯一可以检测键盘事件的组件是InputField
组件.就是这样,它不能用于其他任何用途.
No. The EventSystem is mostly used for raycasting and dispatching events. This is not used to detect keyboard events. The only component from the EventSystem that can detect keyboard events is the InputField
component. That's it and it can't be used for anything else.
检查是否按下了按钮,而没有在Update()中这样做 功能?
Check whether a button is pressed, without doing so in an Update() function?
是的,有一种使用Event.KeyboardEvent
的方法,这需要 OnGUI
函数.
Yes, there is a way with Event.KeyboardEvent
and this requires the OnGUI
function.
void OnGUI()
{
if (Event.current.Equals(Event.KeyboardEvent("W")))
{
print("W pressed!");
}
}
这比将Input.GetKeyDown
功能与Update
功能一起使用要差.我鼓励您坚持使用Input.GetKeyDown
.没问题.
This is worse than using the Input.GetKeyDown
function with the Update
function. I encourage you to stick with Input.GetKeyDown
. There is nothing wrong with it.
如果您要查找没有Input.GetKeyDown
的事件类型 InputSystem ,请使用Unity的新Input API并订阅InputSystem.onEvent
事件.
If you are looking for event type InputSystem without Input.GetKeyDown
then use Unity's new Input API and subscribe to the InputSystem.onEvent
event.
如果您正在寻找类似于IPointerClickHandler
界面的功能,则可以在Input.GetKeyDown
之上实现它.
If you are looking for feature similar to the IPointerClickHandler
interface you can implement it on top of Input.GetKeyDown
.
1 .首先,用System.Enum.GetValues(typeof(KeyCode));
获取所有KeyCode
枚举并将其存储在数组中.
1.First, get all the KeyCode
enum with System.Enum.GetValues(typeof(KeyCode));
and store it in an array.
2 .创建一个接口"IKeyboardEvent"并添加OnKeyDown
之类的功能,就像在IPointerClickHandler
界面中的OnPointerClick
一样.
2.Create an interface "IKeyboardEvent" and add functions such as OnKeyDown
just like OnPointerClick
in the IPointerClickHandler
interface.
3 .从#1 中遍历KeyCode
,并检查是否按下,释放或按住了阵列中的每个键.
3.Loop through the KeyCode
from #1 and check if each key in the array is pressed, released or held down.
4 .获取场景中的所有组件,并检查它们是否实现了IKeyboardEvent
界面.如果是这样,则根据#3 的键状态在界面中调用适当的功能.
4.Get all the components in the scene and check if they implemented the IKeyboardEvent
interface. If they do, invoke the proper function in the interface based on the key status from #3.
这是一个仍可以扩展或改进的功能示例:
Here is a functional example that can still be extended or improved:
附加到一个空的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
一样.
Implement the IKeyboardEvent
interface and the functions from it in your script just like you would with 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);
}
}
这篇关于使用EventSystem进行按键事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!