c# - 如何检测 UI 和游戏对象上的点击/触摸事件

标签 c# unity3d

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

例如,我有一个 Canvas ,其中有 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 的输入 API。您可以根据事件订阅 UI 事件或实现接口(interface)。

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

1 . Image , RawImage Text 组件:

实现所需的接口(interface)并覆盖其功能。下面的示例实现了最常用的事件。

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

如果您检测到的不是 Button Click 按钮,则使用方法 1。例如,Button down 而不是 Button Click,使用 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 零件:

要检测拖动期间 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)
{

}

非 UI 对象:

6 .对于 3D 对象(网格渲染器/任何 3D 碰撞器)

添加 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 Renderer/任何 2D Collider)

添加 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,它根本无法检测到点击。如果您没有它,请自己创建它。

转到游戏对象 ---> UI ---> 事件系统。如果尚不存在,这将创建一个 EventSystem。如果它已经存在,Unity 将忽略它。

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

这仅适用于 UI 对象。它没有 适用于 2D( Sprite 渲染器/任何 2D 碰撞器)或 3D 对象(网格渲染器/任何 3D 碰撞器)。

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

D .如果这是一个二维对象,Physics2DRaycaster未连接到相机。确保 Physics2DRaycaster连接到相机。有关更多信息,请参阅上面的 #7。

E .如果这是一个UI对象,你想用OnBeginDrag等界面功能检测点击, OnPointerClick , OnPointerEnter以及#1 中提到的其他功能,然后 带有检测代码的脚本必须附加到该 UI 对象 你想检测点击。

传真 .此外,如果这是您想要检测点击的 UI 对象,请确保它前面没有其他 UI 对象。如果在您要检测点击的 UI 前面有另一个 UI,它将阻止该点击。

要验证这不是问题,请禁用 Canvas 下的每个对象,除了要检测的对象单击,然后查看单击它是否有效。

关于c# - 如何检测 UI 和游戏对象上的点击/触摸事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41391708/

相关文章:

c# - 如何重构 C# 中的日志记录?

android - Unity android中的水平面检测

c# - 我们如何使用统一在后台保存大量数据?

c# - 与创建委托(delegate)相比,关键字委托(delegate)如何工作

c# - 在 devexpress xtragrid 中单击列标题时选择按列?

c# - unity3d : The type "task" exist in both Unity. 任务和mscorelib

c# - 半正弦公式Unity

c# - 如何将 TextBlock 文本属性设置为字符串资源?

c# - esp8266与Unity之间的udp连接问题

unity3d - ElectronJS中的Unity游戏?