Unity. Использование New Input System и UI
Всем привет!
Начал делать проект в Unity
. Вопрос в том как правильно обрабатывать тап по UI button
на Androind
?
Смысл в том что у меня есть event
, который срабатывает при тапе по экрану. На сцене есть счётчик который считает тапы по экрану +1Damage
(условный кликер). Рядом висит Button
, эта кнопка должна отвечать за какие-то действия, например: нажимая на кнопку покупаешь какой-то баф.
Проблема в том когда тапаешь по кнопке, так же срабатывает и event тапа по экрану который добавляет +1Damage
. Как определять тапнул ты по экрану или по кнопке? Пробовал метод IsPointerOverGameObject()
, он вроде срабатывает, но выдаёт не критическую ошибку о том что его нужно использовать в методе Update
, мне это не подходит. Можете подсказать возможные решения проблемы?
Ответы (2 шт):
Я решил эту проблему следующим образом:
При нажатии на экран нужно проверить попадает ли луч в точке нажатия на UI элемент. За это у меня отвечает следующая функция:
//// проверка нажатия на UI элементы
private bool IsPointerOverUIObject(){
// проверка на идиота
if( EventSystem.current == null ){
Debug.LogError("ВЫ НЕ ДОБАВИЛИ EventSystem на сцену, добавте её!!!");
}
PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
eventDataCurrentPosition.position = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Input.mousePosition.z);
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);
return results.Count > 0;
}
Функция проверяет и если нажатие произошло на UI элемент вернёт TRUE, если вернёт FALSE можно выполнять твой код +1Damage.
Когда будешь обрабатывать нажатие вызови эту функцию и проверь есть ли UI элемент ( твоя кнопка или любая другая ) в точке нажатия:
// если точка на UI элементе то не выполняем действие
if( !IsPointerOverUIObject() ){
// твой код +1Damage исполнится т.к. это не UI элемент
}
else{
// Действие не будет выполнено т.к. нажатие на UI элемент;
}
EventSystem
вообще не нужно использовать напрямую!
Подобно тому, как у тебя есть объект Button
, должен быть объект для клика растянутый на весь экран, который обрабатывает реакцию на клик. Если под кликом находятся сразу несколько элементов, то обработан будет тот, кто выше в иерархии канваса, то есть тот, кто отрисовывается поверх.
Является ли объект, целью обработчики EventSystem
определяет флаг RaycastTarget
, который можно увидеть у Image
и Text
. Если у дочернего Image
стоит флаг RaycastTarget
, то и компоненты на родительском объекте обрабатываются, как это происходит с той-же Button
, где клик на самом деле происходит по Image
или Text
и без них Button
не работает.
Класс Button
обрабатывает событие клика реализуя интерфейс IPointerClickHandler, но он срабатывает при отжатии. Если нужно события касания, то необходимо написать компонент реализующий IPointerDownHandler.
И нет нужды в никаких проверках, тот ли это ёжик и не являешься ли ты жирафом, или другая чушь, которой этот объект заниматься вообще не должен, потому что, его ответственность. Это только реакция на событие и ничего более. Кто и как это событие обрабатывает, не его собачье дело, а занимается этим тот самый EventSystem
, вопросов к которому у нас быть не должно.