ДевЛог #14 - Инвентарь
Предметы в игре уже можно было собирать, но дальше они исчезали в «никуда». Потому что никакого интерфейса и понимания что же было собрано нет. В этот момент игре срочно требуется инвентарь!
Инвентарь он как бы один, но реализовать его я постарался так, чтобы любой ящик, схрон на базе или, например, торговец тоже подпадал под понятие инвентаря.
Для начала надо было чётко понимать что же хочется получить, поэтому хотелки надо описать и разбить на подзадачи.
Хотелки
Разумеется инвентарь (как и любая сущность в игре) делится на логический и интерфейсный. Логический занимается тем, что всё хранит в памяти и всячески перетасосывает, а вот интерфейсный делает красивые подсказки при наведении, рисует иконки, и даже занимается драгэнддропом! Поэтому для начала я определился с тем, что я хочу получить от инвентаря:
- Размер не ограничен и может задаваться от 1 до «сколькоугодно» ячеек
- Многослотовые итема очень усложняют, поэтому не нужны
- Управление мышкой
- Каждый тип итема может уметь стекаться ограниченное кол-во раз
- При подборе стека итемов они должны автоматом собираться в кучку
- При попытке набросить один предмет поверх другого они меняются местами
- Физическое расположение ячеек на экране не привязано к сетке и в целом неважно
- Должно быть легко добавлять новые сущности
Реализация
Реализация была разбита на 2 части, как и описано выше, сделаны они были независимо. В логической части были ячейки и итема, и в графической. После вёрстки интерфейсной части и реализации нескольких интерфейсов вроде IDragHandler и вообще подключения системы EventSystems всё уже работало само. Был итем и его можно было таскать:
Интерфейс
Для возможности перестаскивания итема мне потребовался, как было сказано выше, EventSystems. На камеру был добавлен компонент Physics 2D Raycaster. Он-то и займётся определением на что в UI смотрит наш курсор.
UIItem, что лежит в слоте расширен интерфейсами IDragHandler, IBeginDragHandler, IEndDragHandler. Первый обрабатывает таскание, второй попытку начать тащить, а третий прекращение. Вся хитрость в данном месте была только в том, чтобы для итема, который тащим надо не забывать в begin отключать рейкаст, а в end включать назад. Иначе мы не сможем попасть им в слот!
Также для тултипа в UIItem реализованы интерфейсы IPointerEnterHandler, IPointerExitHandler. Они позволяют легко понять когда рейкастер столкнулся с итемом, чтобы сделать тултип видимым и заполнить данными.
UISlot реализует интерфейс IDropHandler и отслюда даёт команду уже логике на перемещение итема.
Логика
В логической части скриншотов особо не поделать, поэтому как оно всё работает получилось уже при соединении. Вся суть соединения была в том, чтобы залинковать графические ячейки с физическими и… и всё! Дальше всё работает согласно коду:
Работа проведена довольно большая и местами весьма сложная, но я доволен. Очень жду ваших вопросов\критики\пожеланий!
Как обычно чаще и больше информации в телеграмм-канале