首页 文章

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

提问于
浏览
35

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

例如,我有一个画布,有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获取触摸?是否与上述相同?

3 回答

  • 3

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

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

    1 . ImageRawImageText组件:

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

    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组件:

    您可以使用事件注册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 函数 .

    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)
    {
    
    }
    

    NON-UI OBJECTS:

    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渲染器/任何2D对撞机)

    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
    }
    

    对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对象 . 它 doesn't 适用于2D(精灵渲染器/任何2D碰撞器)或3D物体(网格渲染器/任何3D碰撞器) .


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


    D . 如果这是一个2D物体, Physics2DRaycaster 没有连接到相机 . 确保 Physics2DRaycaster 已连接到相机 . 有关更多信息,请参见上面的#7 .


    E . 如果这是一个UI对象,您想要通过接口函数检测点击次数,例如 OnBeginDragOnPointerClickOnPointerEnter 和#1中提到的其他函数,然后 the script with the detection code must be attached to that UI Object ,您要检测点击 .


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

    要验证这不是问题,请禁用“画布”下的每个对象,但要检测的对象除外,然后查看是否有效 .

  • 3

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

  • 71

    你也可以使用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
    
        }
    }
    

相关问题