Another week - another bugs!
На этой неделе не так много было времени потупить над персом
Но то время, что было - я протупил основательно
Вообще, с этим персонажем я нормальную такую кроличью нору расковырял. Концепт персонажа выявил кучу мелких проблем в абстрактных строительных блоках, исправление которых было весьма болезненным, т.к. уже внушительное количество кода написано, и изменить какое-то поведение в общей штуке_нейм - это потенциально уронить половину из того, что раньше работало
Вот один только отскакивающий снаряд проблем принёс:
Эзотерическое застревание снаряда в мобах
Normally снаряд должен долетать до моба и сразу отскакивать в другого
Но иногда он просто застревал в юните и больше ничего не делал
Сначала я думал, что это снаряд как-то проскальзывает коллайдер. Особенно учитывая, что сначала он вообще истерически дёргался внутри юнита, пока я не добавил проверку, которая вталкивает снаряд в центр
Где-то неделю я периодически наблюдал, как эта хрень происходила абсолютно спонтанно, пока не понял, что здесь затесалась гонка состояний
Как вы помните, игра у меня с видом сверху, но спрайты с видом сбоку.
Соответственно, их хитбокс находится в середине тела, а точка, где они стоят, снизу
Что из этого следует? А то, что коллайдеры могут пересекаться!
И вот как раз когда снаряд попадал в такое перехлёстывание, оно и ломалось
- Снаряд прицелился в первого юнита
- Врезался в первого, но также задел и второго
- Таргет сменился на второго
- Игра ждёт коллизию со вторым, но она уже произошла
- Вуаля, снаряд завис
Этот баг на данный момент никак не пофикшен, т.к. с учётом того, как код написан, я пока не придумал, как безболезненно это зафиксить
Да и как оно работать должно, тоже пока хз
- Засчитывать ли демедж сразу, когда два юнита перехлестнулись?
Будет как-то стрёмно выглядеть, что снаряд, летя в одного юнита, продамажил другого - Засчитывать коллизию, только когда снаряд долетел до центра?
Тогда им будет гораздо сложнее целиться, надо усилить аиминг. Услиить аиминг = получить избыточный аиминг там, где он не нужен
В общем, сложно и душно. Оставил как задачку со звёздочкой, ну а пока я просто уменьшил хитбокс самого снаряда, чтобы снизить вероятность такого сценария
Коллизии с CharacterBody2D/Area2D
Ещё очень долгое время снаряд игнорировал края карты и просто в них упирался, и мне дико лень было это фиксить
Всё потому, что в Godot какой-то всратый подход с разделением на "тела" и "зоны". И где-то есть события нужных коллизий, а где-то нет
Ну вот, например, CharacterBody2D (ранее KinematicBody2D), коим является снаряд, не может трэкать, что он попал внутрь какой-то Area2D. Ну или хотя бы коснулся её. Почему? Если он может в неё зайти, почему бы не обработать это событие там же?
Сделали бы какой-то общий тип, от которого наследуются все эти зоны/юниты, проблемы бы не было. Но зачем-то разделили
В итоге код, отвечающий за коллизию, лежит не в снаряде, а в юнитах и в окружении
"Когда в зону хитбокса юнита/края карты попало тело, сообщи ему, что оно попало, если это снаряд" То ли лыжи не едут, то ли я...
Снова TargetStore
Для Bounce я добавил фильтр целей "отсутствует в списке задетых целей", чтобы снаряд отскакивал по уникальным противникам
Но это привело к тому, что снаряд либо аимился на врагов, но не дамажил их; либо, наоборот - дамажил, но летел по прямой
Убил на отладку снарядов/демедж дилера добрых 3 часика. В итоге проблема оказалась вот в этом банальном сегменте, который отвечает за внесение юнита в список:
targets - это массив всех целей, по которым попадал снаряд. После чего я на его основе делаю реактивнйы массив valid_targets - то есть, целей, которые проходят фильтры
И вот юнит такой красивый сначала добавляется в targets, и тем самым тут же проваливает фильтр на следующей строке, из-за чего дальнейшая логика нанесения урона и отскока не срабатывала
А ещё себе фильтр "не содержится в списке задетых целей" в принципе схлопывает сам себя, ведь добавленный в список юнит тут же перестаёт быть валидным элементом этого списка
Пока что я подвязал логику проверки на targets, но это некорректно. Если в дальнейшем потребуется какой-то фильтр, который смотрит именно на поражённых юнитов, реализацию придётся править
На самом деле, поправить не сложно - нужно всего лишь сделать valid_targets не реактивным, а добавлять/удалять вручную. Но на это место подвязано много чего, так что пока не трогаю
В общем, такие пироги. И это лишь Bounce, а там все 4 скилла довольно ребусными вышли
Энивей, я обещал закинуть демку с персом на прошлых выходных. Но, честно говоря, не ожидал, что налутаю столько бажин
Персонаж почти готов, осталось дочинить остальное и добавить анимацию
Зацени, кстати, рунки!
Больше никаких разноцветных кружочков с квадратиками :)