您不使用新 UI 的输入 API。您可以订阅 UI 事件或根据事件实现接口。
以下是检测新 UI 组件上的事件的正确方法:
1.Image, RawImage and Text成分:
实现所需的接口并覆盖其功能。下面的示例实现了最常用的事件。
using UnityEngine.EventSystems;
public class ClickDetector : MonoBehaviour, IPointerDownHandler, IPointerClickHandler,
IPointerUpHandler, IPointerExitHandler, IPointerEnterHandler,
IBeginDragHandler, IDragHandler, IEndDragHandler
{
public void OnBeginDrag(PointerEventData eventData)
{
Debug.Log("Drag Begin");
}
public void OnDrag(PointerEventData eventData)
{
Debug.Log("Dragging");
}
public void OnEndDrag(PointerEventData eventData)
{
Debug.Log("Drag Ended");
}
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Mouse Down: " + eventData.pointerCurrentRaycast.gameObject.name);
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("Mouse Enter");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("Mouse Exit");
}
public void OnPointerUp(PointerEventData eventData)
{
Debug.Log("Mouse Up");
}
}
2.Button成分:
您使用事件来注册按钮点击:
public class ButtonClickDetector : MonoBehaviour
{
public Button button1;
public Button button2;
public Button button3;
void OnEnable()
{
//Register Button Events
button1.onClick.AddListener(() => buttonCallBack(button1));
button2.onClick.AddListener(() => buttonCallBack(button2));
button3.onClick.AddListener(() => buttonCallBack(button3));
}
private void buttonCallBack(Button buttonPressed)
{
if (buttonPressed == button1)
{
//Your code for button 1
Debug.Log("Clicked: " + button1.name);
}
if (buttonPressed == button2)
{
//Your code for button 2
Debug.Log("Clicked: " + button2.name);
}
if (buttonPressed == button3)
{
//Your code for button 3
Debug.Log("Clicked: " + button3.name);
}
}
void OnDisable()
{
//Un-Register Button Events
button1.onClick.RemoveAllListeners();
button2.onClick.RemoveAllListeners();
button3.onClick.RemoveAllListeners();
}
}
如果您检测到除“按钮单击”之外的其他内容,请使用方法 1。例如,“按钮按下”而不是“按钮单击”,请使用IPointerDownHandler
和它的OnPointerDown
方法 1 中的函数。
3.InputField成分:
您使用事件来注册来注册InputField提交:
public InputField inputField;
void OnEnable()
{
//Register InputField Events
inputField.onEndEdit.AddListener(delegate { inputEndEdit(); });
inputField.onValueChanged.AddListener(delegate { inputValueChanged(); });
}
//Called when Input is submitted
private void inputEndEdit()
{
Debug.Log("Input Submitted");
}
//Called when Input changes
private void inputValueChanged()
{
Debug.Log("Input Changed");
}
void OnDisable()
{
//Un-Register InputField Events
inputField.onEndEdit.RemoveAllListeners();
inputField.onValueChanged.RemoveAllListeners();
}
4.Slider成分:
要检测拖动过程中滑块值何时发生变化:
public Slider slider;
void OnEnable()
{
//Subscribe to the Slider Click event
slider.onValueChanged.AddListener(delegate { sliderCallBack(slider.value); });
}
//Will be called when Slider changes
void sliderCallBack(float value)
{
Debug.Log("Slider Changed: " + value);
}
void OnDisable()
{
//Un-Subscribe To Slider Event
slider.onValueChanged.RemoveListener(delegate { sliderCallBack(slider.value); });
}
对于其他事件,请使用Method 1.
5.Dropdown成分
public Dropdown dropdown;
void OnEnable()
{
//Register to onValueChanged Events
//Callback with parameter
dropdown.onValueChanged.AddListener(delegate { callBack(); });
//Callback without parameter
dropdown.onValueChanged.AddListener(callBackWithParameter);
}
void OnDisable()
{
//Un-Register from onValueChanged Events
dropdown.onValueChanged.RemoveAllListeners();
}
void callBack()
{
}
void callBackWithParameter(int value)
{
}
非 UI 对象:
6.对于 3D 对象(网格渲染器/任何 3D 碰撞器)
Add PhysicsRaycaster
然后到相机使用方法 1 中的任何事件.
下面的代码会自动添加PhysicsRaycaster
到主要Camera
.
public class MeshDetector : MonoBehaviour, IPointerDownHandler
{
void Start()
{
addPhysicsRaycaster();
}
void addPhysicsRaycaster()
{
PhysicsRaycaster physicsRaycaster = GameObject.FindObjectOfType<PhysicsRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
}
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}
//Implement Other Events from Method 1
}
7.对于 2D 对象(Sprite 渲染器/任何 2D 碰撞器)
Add Physics2DRaycaster
然后到相机使用方法 1 中的任何事件.
下面的代码会自动添加Physics2DRaycaster
到主要Camera
.
public class SpriteDetector : MonoBehaviour, IPointerDownHandler
{
void Start()
{
addPhysics2DRaycaster();
}
void addPhysics2DRaycaster()
{
Physics2DRaycaster physicsRaycaster = GameObject.FindObjectOfType<Physics2DRaycaster>();
if (physicsRaycaster == null)
{
Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
}
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name);
}
//Implement Other Events from Method 1
}
事件系统故障排除:
在 UI、2D 对象(Sprite 渲染器/任何 2D 碰撞器)和 3D 对象(网格渲染器/任何 3D 碰撞器)上未检测到点击:
A.检查您是否有EventSystem。如果没有 EventSystem,它根本无法检测点击。如果您没有,请自行创建。
Go to 游戏对象--->UI--->事件系统。如果事件系统尚不存在,这将创建一个。如果它已经存在,Unity 将忽略它。
B.UI 组件或带有 UI 组件的 GameObject 必须位于Canvas
。这意味着一个Canvas
必须是 UI 组件的父组件。如果没有这个,EventSystem 将无法运行并且不会检测到点击。
这仅适用于 UI 对象。它doesn't适用于 2D(精灵渲染器/任何 2D 碰撞器)或 3D 对象(网格渲染器/任何 3D 碰撞器)。
C.如果这是一个 3D 对象,PhysicsRaycaster
未连接至相机。确保PhysicsRaycaster
已连接至相机。看#6以上了解更多信息。
D.如果这是一个 2D 对象,Physics2DRaycaster
未连接至相机。确保Physics2DRaycaster
已连接至相机。看#7以上了解更多信息。
E.如果这是一个 UI 对象,您想要使用接口函数检测点击,例如OnBeginDrag
, OnPointerClick
, OnPointerEnter
以及中提到的其他功能#1 then 带有检测代码的脚本必须附加到该 UI 对象你想检测点击。
F另外,如果这是您想要检测点击的 UI 对象,请确保其前面没有其他 UI 对象。如果您想要检测点击的 UI 前面有另一个 UI,它将阻止该点击。
要验证这不是问题,请禁用画布下的每个对象(除了您想要检测点击的对象),然后查看点击是否有效。