void Update(){
if (Input.GetKeyDown("W"))
DoSomething();
}
使用Unity的EventSystem有没有办法做到以下几点?换句话说,是否有像 IPointerClickHandler 这样的接口的实现,例如,检查按钮是否被按下,而不是在 Update()函数中这样做? / p>
答案 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
界面中添加OnPointerClick
等IPointerClickHandler
等功能。
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");
}
}
}