Как обнаружить события нажатия / касания в интерфейсе пользователя и GameObjects

Как обнаружить объект пользовательского интерфейса на холсте на Touch в Android?

Например, у меня есть холст, который имеет 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? Это то же самое с выше или нет?

3 ответа

Решение

Вы не используете API ввода для нового пользовательского интерфейса. Вы подписываетесь на события пользовательского интерфейса или реализуете интерфейс в зависимости от события.

Вот правильные способы обнаружения событий в новых компонентах пользовательского интерфейса:

1 Image, RawImage а также Text Компоненты:

Реализуйте необходимый интерфейс и переопределите его функцию. В приведенном ниже примере реализованы наиболее часто используемые события.

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

Если вы обнаруживаете что-то, кроме нажатия кнопки на кнопке, используйте способ 1. Например, нажмите кнопку вниз, а не нажатие кнопки, используйте 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 Составная часть:

Чтобы определить, когда значение ползунка изменяется во время перетаскивания:

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

}

НЕОБЪЕКТНЫЕ ОБЪЕКТЫ:

6.Для 3D-объектов (Mesh Renderer/ любой 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-коллайдер)

добавлять 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:

Не обнаружено щелчков на интерфейсе пользователя, 2D-объектах (Sprite Renderer/ любой 2D-коллайдер) и 3D-объектах (Mesh Renderer/ любой 3D-коллайдер):

. Проверьте, что у вас есть EventSystem. Без EventSystem он не может обнаружить щелчки вообще. Если у вас его нет, создайте его сами.


Перейдите в GameObject ---> UI ---> Система событий. Это создаст EventSystem, если она еще не существует. Если он уже существует, Unity просто проигнорирует это.


Б. Компонент пользовательского интерфейса или GameObject с компонентом пользовательского интерфейса должен находиться под Canvas, Это означает, что Canvas должен быть родителем компонента пользовательского интерфейса. Без этого EventSystem не будет работать и щелчки не будут обнаружены.

Это относится только к объектам пользовательского интерфейса. Это не относится к 2D (Sprite Renderer/ любой 2D-коллайдер) или 3D-объектам (Mesh Renderer/ любой 3D-коллайдер).


C. Если это 3D-объект, PhysicsRaycaster не прикреплен к камере. Удостоверься что PhysicsRaycaster прикреплен к камере. См. № 6 выше для получения дополнительной информации.


D. Если это 2D объект, Physics2DRaycaster не прикреплен к камере. Удостоверься что Physics2DRaycaster прикреплен к камере. См. № 7 выше для получения дополнительной информации.


E. Если это объект пользовательского интерфейса, на котором вы хотите обнаружить щелчки с помощью функций интерфейса, таких как OnBeginDrag, OnPointerClick, OnPointerEnter и другие функции, упомянутые в #1, затем сценарий с кодом обнаружения должен быть присоединен к тому объекту пользовательского интерфейса, на котором вы хотите обнаружить щелчок.


Кроме того, если это объект пользовательского интерфейса, на котором вы хотите обнаруживать щелчки, убедитесь, что перед ним нет другого объекта пользовательского интерфейса. Если перед тем, который вы хотите обнаружить, есть другой пользовательский интерфейс, он будет блокировать этот щелчок.

Чтобы убедиться, что это не проблема, отключите каждый объект в Canvas, кроме того, который вы хотите обнаружить, щелкните, затем посмотрите, работает ли щелчок.

Вы можете добавить EventTrigger Componenet для ваших элементов пользовательского интерфейса, которые уже имеют эти Events тебе просто нужно пройти method/Function на конкретное событие.

Вы также можете использовать OnMouseDown. OnMouseDown вызывается, когда пользователь нажимает кнопку мыши, находясь над элементом GUIElement или 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() по вопросам мобильной производительности и мультитач.

Этот код работает с объектами пользовательского интерфейса для множественных касаний

В своем ответе я использую элемент Image с тегом "Button", и у него есть сценарий ButtonController с общедоступным методом ButtonDown(), который должен вызываться, когда пользователь касается элемента Image.

Примечание: элемент изображения имеет 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();
            }       
        }
    }
}
Другие вопросы по тегам