Лобби: день, когда всё сломалось и починилось
Привет! Сегодня был один из тех дней, когда садишься в 9 утра, а встаешь в 11 вечера и не понимаешь, куда делось время. Рассказываю что такое жизнь инди.
Что такое Лобби
Это экран перед каждым боем — здесь собираешь отряд из своих героев, выбираешь пресет (их до пяти штук), назначаешь бустер и жмёшь «В БОЙ». Звучит просто, но под капотом есть приличный слой логики.
Что сделал сегодня
Посадка и снятие героев. Тапаешь на героя в коллекции → открывает карточку → жмёшь «Выбрать» → герой занимает первый свободный слот авангарда (1→6), затем резерв (7→10), когда авангард заполнится. Тапаешь по занятому слоту → та же карточка, но с ключом «Снять с поста». Герой в коллекции при этом затемняется — он уже в отряде, выбрать повторно нельзя.
Мощь отряда. Важный момент: резерв (слоты 7–10) не входит в сумму, пока авангард не заполнен полностью. Числа оформляется пробелами: 1 105 000 вместо 1105000— читается намного лучше. Реализовано через утилиту Zero-alloc stackalloc без лишних аллокаций.
Галочка сохранения и В БОЙ. Галочка светится только тогда, когда есть несохранённые изменения, и хотя бы один герой в авангарде. «В БОЙ» смотрит на уровне аккаунта:
Уровни 1–20: достаточно одного героя
Уровни 21–50: нужен полный авангард (6/6)
Уровень 51+: полный отряд (10/10)
Старый сохранённый пресет не нарушает этого правила — поднял уровень, иди переукомплектовывайся.
Коллекция фильтров. Раса, класс, атрибут. Мультивыбор внутри категории (ИЛИ) И между категориями. Выбрал «Воин» + «Эльфы» — покажет только эльфов-воинов. Драконы передают любой классовый фильтр — они универсалы. Сортировка: первые герои уже в отряде, потом по редкости, атрибуту, мощи.
Баги
Баг двойного клика — старый друг, встречавший меня уже раз пять. Попап не реагирует на первое нажатие, только на второе. Причина каждый раз одна и та же: объект был неактивен на сцене, первый клик его активирует, в Awakeработе Hide() который тут же гасит контент обратно. Второй клик уже работает нормально. Лечение: первая строка любая Show()— это gameObject.SetActive(true), без исключений. Звучит очевидно, но Unity об этом никак не предупреждает.
Блокировка фильтров и засветка экрана. Когда вы открываете список расы или класса, вам нужно щелкнуть в любом месте экрана и закрыть его. Для этого есть невидимый FilterDropBlocker— прозрачный объект на всем экране. Сделали его, всё заработало, но при открытии весь экран чуть-чуть засветился. Два часа искал причину. Оказалось: утилита UiRaycastUtility.EnsureSolidRaycast подставила белый спрайт 1×1 с альфа=0,004 — вроде незаметно, но на экране давалось лёгкое свечение. Убрал один вызов — засветление исчезло.
Про безопасность
Между делом проверил защиту от читов. Смоделированный сценарий: игрок каким-то образом подменяет данные в запросе и отправляет «у меня 500 энергии», когда на самом деле 100.
Сервер проигнорировал, что прислал клиент, сам заглянул в свое хранилище, записал 1 единицу и вернул внешний баланс. Это фундаментальная принципиальная структура: клиент только рисует, сервер решает.
Также завел чеклист — список всего, что нужно закрыть перед релизом: инфраструктура, данные, требования платформ (RuStore, Steam, Яндекс Игры). Лучше подумать об этом заранее, чем потом в панике. ;D
Что дальше
Остался финальный этап лобби — регрессия по полному чеклисту и тесту на первом телефоне. Потом переходим к боевой сцене.
До следующего девблога! 🛡
Следить за разработкой: Вконтакте Тереграмм