如何在UI和GameObjects上检测单击/触摸事件
如何在Android中的Canvas on Touch上检测UI对象?
例如,我有具有5个对象,诸如帆布Image
,RawImage
,Buttons
,InputField
等。
当我触摸Button UI对象时,请执行一些操作。每个按钮在单击时都会执行不同的过程。
代码如下所示:
private void Update()
{
if (Input.touches.Length <= 0) return;
for (int i = 0; i < Input.touchCount; i++)
{
if (Button1.touch)
if (Input.GetTouch(i).phase == TouchPhase.Began)
login();
else if (Button2.touch && Input.GetTouch(i).phase == TouchPhase.Began)
LogOut();
}
}
那怎么办呢?
第二:如何检测Gameobject接触?与上面相同吗?
-
您不会在新的UI中使用Input API。您订阅UI事件或根据事件实现接口。
这些是检测新UI组件上的事件的正确方法:
实现所需的接口并覆盖其功能。下面的示例实现最常用的事件。
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,然后使用方法1。例如,按下按钮而不单击按钮单击,请使用方法1中的按钮
IPointerDownHandler
及其OnPointerDown
功能。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); }); }
对于其他事件,请使用 方法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) { }
非用户界面对象:
6。 对于3D对象(网格渲染器/任何3D碰撞器)
添加
PhysicsRaycaster
到摄像机,然后 使用方法1中的任何事件 。以下代码将自动添加
PhysicsRaycaster
到main中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 Renderer /任何2D Collider)
添加
Physics2DRaycaster
到摄像机,然后 使用方法1中的任何事件 。以下代码将自动添加
Physics2DRaycaster
到main中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 }
对EventSystem进行故障排除:
在UI,2D对象(Sprite Renderer /任何2D Collider)和3D对象(Mesh Renderer /任何3D
Collider)上未检测到点击:一 。检查你有的EventSystem。没有EventSystem,它根本无法检测到点击。如果没有,请自己创建。
进入 游戏对象 -–> 用户界面 - > 事件系统
。如果尚不存在,则会创建一个EventSystem。如果已经存在,Unity只会忽略它。
B .UI组件或带有UI组件的GameObject必须在之下
Canvas
。这意味着a
Canvas
必须是UI组件的父级。否则,EventSystem将无法运行,并且将无法检测到点击。这仅适用于UI对象。它 并不 适用于2D(精灵渲染器/任何2D撞机)或3D对象(网格渲染器/任何3D撞机)。
C。
如果这是3D对象,PhysicsRaycaster
则未连接到相机。确保已将PhysicsRaycaster
其连接到相机。有关更多信息,请参见上面的
#6 。
D。
如果这是2D对象,Physics2DRaycaster
则未连接到相机。确保已将Physics2DRaycaster
其连接到相机。有关更多信息,请参见上面的
#7 。
Ë
。如果这是您要检测与接口功能,如点击一个UI对象OnBeginDrag
,OnPointerClick
,OnPointerEnter
和中提到的其它功能
#1 然后 与检测代码的脚本必须附加到UI对象 要检测点击。
F。 此外,如果这是您要检测点击的UI对象,请确保前面没有其他UI对象。如果您要检测点击的前面有另一个UI,它将阻止该点击。
要验证这不是问题,请禁用“画布”下的所有对象,但要检测的对象除外,请单击并查看其是否有效。