C# 如何检测UI和游戏对象上的点击/触摸事件
如何在android中检测触摸屏上的UI对象 例如,我有一个画布,它有5个对象,例如C# 如何检测UI和游戏对象上的点击/触摸事件,c#,unity3d,C#,Unity3d,如何在android中检测触摸屏上的UI对象 例如,我有一个画布,它有5个对象,例如图像,绘图图像,按钮,输入字段等等 当我触摸按钮UI对象时,然后做一些事情。单击每个按钮时会执行不同的过程,具体取决于 代码如下所示: private void Update() { if (Input.touches.Length <= 0) return; for (int i = 0; i < Input.touchCount; i++) { if (B
图像
,绘图图像
,按钮
,输入字段
等等
当我触摸按钮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();
}
}
private void Update()
{
如果(Input.touchs.Length您不使用新UI的输入API。您可以根据事件订阅UI事件或实现接口
以下是检测新UI组件上事件的正确方法:
1,以及组件:
实现所需的接口并重写其功能。下面的示例实现了最常用的事件
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。组件:
您可以使用事件注册按钮单击:
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中的ipInterDownHandler
及其OnPointerDown
功能
3。组件:
您可以使用事件注册来注册InputField submit:
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。组件:
要在拖动过程中检测滑块值何时更改,请执行以下操作:
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组件
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。用于三维对象(网格渲染器/任何三维碰撞器)
将PhysicRayCaster
添加到相机,然后使用方法1中的任何事件
下面的代码将自动将PhysicsRaycaster
添加到主摄像机
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
}
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对象(精灵渲染器/任何2D碰撞器)和3D对象(网格渲染器/任何3D碰撞器)上未检测到单击:
A检查您是否有EventSystem。如果没有EventSystem,它根本无法检测到点击。如果您没有,请自己创建
转到GameObject-->UI-->Event System。如果它还不存在,这将创建一个EventSystem。如果它已经存在,Unity将忽略它
B。具有UI组件的UI组件或游戏对象必须位于画布下。这意味着画布必须是UI组件的父级。否则,EventSystem将无法运行,并且不会检测到单击
这仅适用于UI对象。它不适用于2D(精灵渲染器/任何2D碰撞器)或3D对象(网格渲染器/任何3D碰撞器)
C。如果这是一个3D对象,PhysicRayCaster
未连接到相机。请确保将PhysicRayCaster
连接到相机。有关详细信息,请参阅上文第6页
D。如果这是一个2D对象,Physics2DRaycaster
未连接到相机。请确保将Physics2DRaycaster
连接到相机。有关详细信息,请参阅上文第7页
E。如果这是一个用户界面对象,您希望通过界面功能(如OnBeginDrag
、OnPointerClick
、OnPointerEnter
和#1中提到的其他功能)来检测点击,那么带有检测代码的脚本必须附加到要检测点击的用户界面对象上
F。此外,如果这是要检测单击的UI对象,请确保前面没有其他UI对象。如果要检测单击的UI对象前面有另一个UI,它将阻止该单击
要验证这不是问题所在,请禁用画布下的每个对象,但要检测的对象除外,单击,然后查看单击是否有效。您可以将EventTrigger
Componenet添加到已经具有这些事件的UI元素中。
您只需在特定事件上传递方法/函数即可。 您也可以使用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
}
}
请勿使用OnMouseDown()解决移动性能和多点触摸问题
此代码适用于多点触摸的UI对象
在我的回答中,我使用带有“按钮”标记的图像元素,它有一个按钮控制器脚本,带有一个按钮向下()公共方法,当用户触摸图像元素时,应该调用该方法
注意:图像元素有一个2D碰撞器
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
使用UnityEngine.EventSystems;
公共类TouchScript:MonoBehavior
{
无效更新()
{
PointerEventData指针=新的PointerEventData(EventSystem.current);
List raycastResult=新列表();
foreach(输入触摸,触摸)
{
if(touch.phase.Equals(touch.phase.begind))
{
pointer.position=touch.position;
EventSystem.current.RaycastAll(指针,raycastResult);
foreach(RaycastResult结果为RaycastResult)
{
如果(result.gameObject.tag==“按钮”)
{
result.gameObject.GetComponent().ButtonDown();
}
}
raycastResult.Clear();
}
}
}
}
UI API适用于移动设备和桌面。这是它的优点,根本不是问题。我将在稍后更新它,以包括其他3D(网格渲染器/碰撞器)和2D(精灵/2D碰撞器)。添加了滑块和3D、2D示例。这就是您需要的
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class TouchScript : MonoBehaviour
{
void Update()
{
PointerEventData pointer = new PointerEventData(EventSystem.current);
List<RaycastResult> raycastResult = new List<RaycastResult>();
foreach (Touch touch in Input.touches)
{
if(touch.phase.Equals(TouchPhase.Began))
{
pointer.position = touch.position;
EventSystem.current.RaycastAll(pointer, raycastResult);
foreach(RaycastResult result in raycastResult)
{
if(result.gameObject.tag == "Button")
{
result.gameObject.GetComponent<ButtonController>().ButtonDown();
}
}
raycastResult.Clear();
}
}
}
}