如何检测UI和GameObjects上的点击/触摸事件

如何在Android上的Canvas on Touch上检测UI对象?

例如,我有一个canvas,有5个对象,如ImageRawImageButtonsInputField等。

当我触摸按钮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获取触摸? 是否与上述相同?

您不要将Input API用于新UI。 您可以根据事件订阅UI事件或实现界面。

这些是检测新UI组件上事件的正确方法:

1ImageRawImageText组件:

实现所需的接口并覆盖其function。 下面的示例实现了最常用的事件。

 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"); } } 

2Button组件:

您可以使用事件注册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中的IPointerDownHandler及其OnPointerDown函数。

3InputField组件:

您使用事件注册以注册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(); } 

4Slider组件:

要在拖动期间检测滑块值何时更改:

 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

5Dropdown组件

 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对撞机)

PhysicsRaycaster添加到相机然后使用方法1中的任何事件

下面的代码会自动将PhysicsRaycaster添加到主Camera

 public class MeshDetector : MonoBehaviour, IPointerDownHandler { void Start() { addPhysicsRaycaster(); } void addPhysicsRaycaster() { PhysicsRaycaster physicsRaycaster = GameObject.FindObjectOfType(); if (physicsRaycaster == null) { Camera.main.gameObject.AddComponent(); } } public void OnPointerDown(PointerEventData eventData) { Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name); } //Implement Other Events from Method 1 } 

7.对于2D对象(Sprite渲染器/任何2D对撞机)

Physics2DRaycaster添加到Camera,然后使用方法1中的任何事件

下面的代码会自动将Physics2DRaycaster添加到主Camera

 public class SpriteDetector : MonoBehaviour, IPointerDownHandler { void Start() { addPhysics2DRaycaster(); } void addPhysics2DRaycaster() { Physics2DRaycaster physicsRaycaster = GameObject.FindObjectOfType(); if (physicsRaycaster == null) { Camera.main.gameObject.AddComponent(); } } public void OnPointerDown(PointerEventData eventData) { Debug.Log("Clicked: " + eventData.pointerCurrentRaycast.gameObject.name); } //Implement Other Events from Method 1 } 

对EventSystem进行故障排除:

在UI,2D对象(Sprite渲染器/任何2D对撞机)和3D对象(网格渲染器/任何3D对撞机)上未检测到任何点击:

A.检查您是否有EventSystem。 没有EventSystem,它根本无法检测到点击次数。 如果您没有,请自行创建。


转到GameObject —> UI —> Event System 。 如果它还不存在,这将创建一个EventSystem。 如果它已经存在,Unity将忽略它。


B.具有UI组件的UI组件或GameObject必须位于Canvas 。 这意味着Canvas必须是UI组件的父级。 如果没有这个,EventSystem将无法运行,也不会检测到点击。

这仅适用于UI对象。 它不适用于2D(精灵渲染器/任何2D碰撞器)或3D物体(网格渲染器/任何3D碰撞器)。


C.如果这是3D对象,则PhysicsRaycaster不会连接到相机。 确保将PhysicsRaycaster连接到相机。 有关更多信息,请参阅上面的#6


D.如果这是2D对象,则Physics2DRaycaster未连接到相机。 确保将Physics2DRaycaster连接到相机。 有关更多信息,请参见上面的#7


E.如果这是一个UI对象,您想要通过接口函数(如OnBeginDragOnPointerClickOnPointerEnter#1中提到的其他函数)检测点击次数,那么带有检测代码的脚本必须附加到您要检测的UI对象上点击。


F.同样,如果这是一个想要检测点击次数的UI对象,请确保其前面没有其他UI对象。 如果您要检测的UI前面有另一个用户界面点击,则会阻止该点击。

要validation这不是问题,请禁用“canvas”下的每个对象,但要检测的对象除外,然后查看是否有效。

您可以将EventTrigger Componenet添加到已经具有这些Events UI元素,您只需要在特定事件上传递method/Function

你也可以使用OnMouseDown。 当用户在GUIElement或Collider上按下鼠标按钮时,将调用OnMouseDown。 此事件将发送到Collider或GUIElement的所有脚本。

 using UnityEngine; using System.Collections; using UnityEngine.SceneManagement; // The new load level needs this public class ExampleClass : MonoBehaviour { void OnMouseDown() { // Edit: // Application.LoadLevel("SomeLevel"); // Application.LoadLevel() is depreciating but still works SceneManager.LoadScene("SomeLevel"); // The new way to load levels } }