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

Den*_*Liu 58 c# unity-game-engine

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

例如,我有具有5个对象,诸如帆布Image,RawImage,Buttons,InputField等.

当我触摸按钮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();
    }
}
Run Code Online (Sandbox Code Playgroud)

那怎么办呢?

第二:如何检测Gameobject获取触摸?是否与上述相同?

Pro*_*mer 121

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

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

1.Image,RawImageText组件:

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

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您在按钮检测比巴顿点击其他的东西,然后使用方法.例如,按钮并没有按钮点击,利用IPointerDownHandlerOnPointerDown从方法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();
}
Run Code Online (Sandbox Code Playgroud)

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); });
}
Run Code Online (Sandbox Code Playgroud)

对于其他事件,请使用方法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)
{

}
Run Code Online (Sandbox Code Playgroud)

非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
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

对EventSystem进行故障排除:

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

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


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


B.具有UI组件的UI组件或GameObject必须位于a Canvas.这意味着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前面有另一个用户界面,则会阻止该点击.

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

  • 添加了滑块和 3D、2D 示例。这就是您现在应该使用的输入系统或旧的 Raycast 方式。 (2认同)
  • OnClick()不是接口的函数.你可能意味着使用`IPointerClickHandler`接口的`OnPointerClick`.请再次阅读我的回答.*我的答案中的所有*都应该适用于桌面和移动设备.我看到一些答案告诉人们使用'OnPointerClick`作为Button组件.这是错的.它会工作,但是当你这样做时,他们不知道有什么错误.要检测单击Button的时间,请使用我的答案中使用"AddListerner"的事件.不要使用`OnPointerClick`检测按钮单击.`OnPointerClick`适用于非Button的其他组件. (2认同)
  • 了解将这些脚本附加(或不附加)到哪些游戏对象将很有用。有些是显而易见的(按钮),但我应该将#1放在我想要单击的对象上吗?在相机上?#7 会出现在我的游戏对象或相机上吗?或者是在其他地方? (2认同)

小智 5

您可以将EventTriggerComponenet 添加到您的UI元素中,而这些元素Events只需要传递method/Function特定事件即可。


小智 5

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

    }
}
Run Code Online (Sandbox Code Playgroud)