Чудесный UI Unity5 или приключения кнопки

Чудесный UI Unity5 или приключения кнопки Unity, Unity5, Gamedev, Мобильные игры, Android, Платформер, Игры unity, Длиннопост

Затеял я не давно игрулю на юнити и в процессе разработки игры под андроид, наткнулся на одну особенность, оказывается в юнити нет нормальной обработки событий кнопки UI.Button, таких каких Up и Down.

Чудесный UI Unity5 или приключения кнопки Unity, Unity5, Gamedev, Мобильные игры, Android, Платформер, Игры unity, Длиннопост

На событие OnClick моя функция ClickBtnRight выполнялась лишь один раз, в одном кадре, а если мы удерживаем кнопку то функция уже не запускается. В чем была проблема, пока кнопка нажата мне нужно двигать персонажа вправо, и для этого мне нужно знать когда на кнопку нажали и когда ее отжали. Допустим onClick() позволяет узнать когда нажали на кнопку, но никаких стандартных методов узнать когда ее отжали нету. Поискав немного в Google я узнал что это распространенная проблема и даже нашел ее решение, которое заключалось в том что бы выбрать изменение события на кнопке по цвету, т.е. ColorTint:

Чудесный UI Unity5 или приключения кнопки Unity, Unity5, Gamedev, Мобильные игры, Android, Платформер, Игры unity, Длиннопост

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

Но я решил проблему иначе, выбрав события на кнопке по спрайту, т.е. SpriteSwap:

Чудесный UI Unity5 или приключения кнопки Unity, Unity5, Gamedev, Мобильные игры, Android, Платформер, Игры unity, Длиннопост

Я начал каждый кадр отлавливать какой же сейчас спрайт текущей на кнопке, и мне это позволило реализовать

if (btnLeft.GetComponent<Image> ().overrideSprite ==

btnLeft.GetComponent<Button> ().spriteState.pressedSprite) {


//двигаем героя влево


} else if (btnRight.GetComponent<Image> ().overrideSprite ==

btnRight.GetComponent<Button> ().spriteState.pressedSprite) {


//двигаем героя вправо


}


Когда условия срабатывало я просто двигал героя на определенное значение влево или вправо. Так же замечу что конструкция должна быть if else if что бы никогда не сработала обработка одновременно нажатия влево и вправо.

Вот как в целом выглядят у меня кнопки:

Чудесный UI Unity5 или приключения кнопки Unity, Unity5, Gamedev, Мобильные игры, Android, Платформер, Игры unity, Длиннопост

Так же если вам надо что бы кнопка не выделялась при нажатии просто закидывайте в строчку Pressed Sprite тот же спрайт кнопки просто с другим названием, как собственно сделал я.


Меня так же часто спрашивают знакомые как же я разрабатываю игру, и я снял видео о том как это происходит в живую на экране...интересно ли вам будет увидеть подобное...это 2 часа например видео моей работы, а работаю я в тишине)))


Надеюсь вам понравиться мой пост и я продолжу выкладывать какие нибудь важные моменты разработки, пишите что бы вы хотели услышать, я постараюсь ответить или сделаю пост.


Разрабатываю на Unity 5.3.2 на C# под андроид.


Игра в стадии разработки...хотел показать как двигается персонаж...но пока не могу выкладывать видео)))


Это мой первый пост не судите строго :) Вот вам картинка из игры..

Чудесный UI Unity5 или приключения кнопки Unity, Unity5, Gamedev, Мобильные игры, Android, Платформер, Игры unity, Длиннопост

Лига Разработчиков Видеоигр

6.8K постов22.2K подписчиков

Добавить пост

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

- Пост должен быть содержательным и интересным для пользователей, нести пользу для сообщества

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"

Вы смотрите срез комментариев. Показать все
6
DELETED
Автор поста оценил этот комментарий

С применительной точки зрения, нужно использовать компонент Event Trigger.

С программной точки зрения


using UnityEngine.EventSystems;


[DisallowMultipleComponents]

public sealed class SomeClass : MonoBehaviour, IPointerDownHandler, IPointerUpHandler

{

____public void OnPointerDown(PointerEventData eventData)

____{

____}


____public void OnPointerUp(PointerEventData eventData)

____{

____}

}

раскрыть ветку (17)
2
DELETED
Автор поста оценил этот комментарий

Далее создать элемент канваса Image и закинуть этот скрипт на элемент. Если заморочиться, то можно и свое событие onClick добавить в скрипт. В итоге получаем аналогичную кнопку.


И хочу порекомендовать в дальнейшем не пробовать реализовывать тупые советы из интернета типа определять по цвету или по картинке ибо это настолько не стабильно, что может перестать работать например если за окном дождь пошел. :))

раскрыть ветку (1)
Автор поста оценил этот комментарий

я все сделал как тут советовали в коммента на триггере событий, работает отлично.

Автор поста оценил этот комментарий

Поддерживаю @DiElGl, реализовать 2 интерфейса и всё будет работать как надо без этих безумных костылей.

Автор поста оценил этот комментарий

И если еще хорошенько подумать - использовать CrossPlatformInput и не изобретать велосипед. Да и для движения удобней джой использовать, а не кнопки. Нажал в любом месте экрана например, рисуется стик и начинается управление. И экран не захламляется и более точные движения получаются. Мы когда предыдущую игру писали на андроид - управление было и на джойстике (физический который, от XBOX или PS) и на таче и хз на чем еще, может кому взбредет в голову клаву подрубить к андроид-устройству. Все работало и кода было куда меньше чем здесь. Единственное 2 раза в секунду проверял с какого устройства идет инпут и менял метод ввода (например если на джойстике начал управлять - кнопки с экрана скрывались, чтоб не мешать и т.д.)

раскрыть ветку (7)
Автор поста оценил этот комментарий

Пример в студию)) а то все только говорят

раскрыть ветку (6)
Автор поста оценил этот комментарий

assets->importpackage->crossplatforminput



вот простейший кусок кода, в данном случае для джоя, с кнопкой будет одна строчка


h = CrossPlatformInputManager.GetAxis (axisHorizontal);

v = CrossPlatformInputManager.GetAxis (axisVertical);

transform.position+=new Vector2(h,v);


получаем полноценный хэндл управления

кнопке задаем этот axis (в project settings->input)

нажата - значение 1, отпущена - значение 0. Так же задается скорость изменения значения, чтобы например поворачивать колеса у машины не сразу в крайние положения, а постепенно или чтобы персонаж разгонялся и тормозил при движении

раскрыть ветку (5)
Автор поста оценил этот комментарий

Это оказывается пакет качать надо, я то думаю почему ничего нет..

А это не усложнит по сравнению с тригерром событий? Я делаю на андроид...тут вес приложения важен тоже, этот ассет много добавляет МБ в игру?

Вообще я не планирую на пк и вебджиэль, но это хорошая тема crossplatforminput

раскрыть ветку (4)
1
Автор поста оценил этот комментарий

какой пакет? тебе там 2 скрипта нужно. ButtonHandler и CrossPlatformInput. Если бы вес приложения был важен, то на юнити бы не писал:) он пустой проект метров на 5 собирает, а эти скрипты дай бог если килобайт 5 добавят к весу. Юнити собирает только то, на что есть ссылки в собираемых сценах. У тебя может быть пакетов добавлено на 50 гигов, но apk он соберет на 5 метров.


Вот я использую в проекте, но тут и джой и куча других скриптов еще.

Иллюстрация к комментарию
раскрыть ветку (3)
Автор поста оценил этот комментарий

Пока наверное оставлю триггер событий, все таки он же существует значит это тоже правильное решение)) Да и под кнопки уже все расписано, но учту, это очень полезная штука, спасибо.

раскрыть ветку (2)
Автор поста оценил этот комментарий

не за что. по сути кроссплатформинпут тоже работает через events trigger. В след проекте про него не забывай тогда:)

раскрыть ветку (1)
Автор поста оценил этот комментарий

Мне бы этот до ума до вести, я на днях еще пост сделаю об интересной штуки как реализовал персонажа. Вообще практически первый мой проект. Делаю один...поэтому камней подводных много

DELETED
Автор поста оценил этот комментарий
С программной точки зрения нужно импортировать пространство EventSystems. Это пространство отвечает за систему событий взаимодействия, как для интерфейса, так и для физического мира. В этом пространстве объявлен набор интерфейсов всех возможных взаимодействий. Для того, чтобы это все работало на сцене должны быть три компонента:

- EventSystem,

- Input Module (Standalone Input/Touch Input)

- Raycaster(Graphic Raycaster/Physics Raycaster/Physics 2D Raycaster)

Ещё раз акцентирую внимание: это работает не только для UI. И обычные объекты можно мышкой по экрану тягать.

Автор поста оценил этот комментарий

Насколько я понял эти события IPointerDownHandler, IPointerUpHandler срабатывают только на мышку. А не на тач, но я недо-программист)) Я решил так ка крешил и вполне доволен, думаю это меньше нагружает систему чем добавления целой системы событий из которых нужно только малая часть :)

раскрыть ветку (4)
DELETED
Автор поста оценил этот комментарий
1. Как только ты подключаешь uGUI автоматически создается эта система в сцене, т.к. uGUI работает за счет Graphic Raycaster. Он добавляется на Canvas.

2. Это работает и для тача при наличии в сцене компонента Touch Input Module.

3. В каждое событие присылается присылается PointerEventData, который содержит избыток информации по всем параметрам указателЕЙ. Их может быть много, по количеству пальцев. И да в этой структуре есть информация о пальцах (тачах).


https://docs.unity3d.com/ScriptReference/EventSystems.Pointe...

раскрыть ветку (3)
Автор поста оценил этот комментарий

я это все читал, и как это работает не понял, не нашел не одного примера в доках. Ну в целом стоит этим пользоваться если все решается в один if else if?

раскрыть ветку (2)
3
DELETED
Автор поста оценил этот комментарий

Ну, тебе потом поддерживать этот код, так что решай сам. Я же одно точно могу сказать: кто радуется решению проблемы через elif, тот только elif-ы делать и научится.

раскрыть ветку (1)
Автор поста оценил этот комментарий

Ну я только учусь :)

Опиши пример как пользоваться тригерром событий?

Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку