Статья удалена
В этой статье я расскажу, как задать цвет частиц приземления и следа за персонажем в зависимости от объекта, по которому движется персонаж.
Привет. Сейчас я работаю над игрой Pirates: Mystery of Skeleton Island. Я хочу рассказать о том, как мне удалось достичь эффекта окрашивания частиц после приземления и во врмя движения в зависимости от типа поверхности, которой касается пират. Работа ведётся в движке Unity (версии 2019.4), но этот подод применим в любой среде.
1. Добавим кастомные материалы
Для этого я создал скрипт со следующим кодом, где перечислю список потенциальных материалов, у которых будет отличный от других цвет:
Дальше прикрепляем скрипты к GameObject-ам, выбераем тип из выпадающего списка и сохраняем в префабы.
2. Создаём сами частицы
Чтобы не получился класс-монстр с кодом-спагетти, прибегая к принципу SRP, для менеджмента частицами игрока я создал класс PirateParticles.
Сначала добавлю поля для указания систем частиц в редакторе Unity. Для лучшей читаемости и удобства стоит добавить префикс 'Prefab'.
У меня будет 2 системы частиц- landGround будет проигрываться при приземлении после прыжка, trailEffect- во время бега.
Дальше перечислю градиенты, из которых будут браться цвета частиц. Каждому градиенту соответствует свой MaterialType.
Дальше определю переменные, где будут храниться инстанцы частиц, чтобы не спавнить их каждый раз- это крайне негативно сказалось бы на производительности. Посоветую не использовать префикс 'InScene'.
Теперь повесим скрипт на персонажа, создадим системы частиц и определим значения в редакторе:
Далее создаю функции, которые будут вызываться для спавна этих двух систем частиц, как очевидно из названия:
3. Спавн частиц
Вызываю SpawnTrailParticles() из скрипта ввода и обработки состояний персонажа.
timeBtwTrails- таймер, инициализируйте со значением желаемого промежутка времени между спавном частиц бега.
SpawnLandGroundParticles() вызывается из всё того же скрипта.
4. Проверка материала поверхности.
Дальше наконец-то определим функцию CheckGroundType() в скрипте чатиц:
Про MultipleRaycast я напишу ближе к концу статьи. Вы можете написать тело OnceRaycastAll() прямо в CheckGroundType(). Я оставил это для выяснения более надёжного способа проверки земли. В статье будут рассмотрены оба.
Определю OnceRaycastAll(), но сначала инициализирую высоту спрайта персонаж, и длину луча. В вашем случае знание может отличаться.
Дальше я покажу функцию OnceRaycastAll().
Определяется она с тем же аргументом, что и CheckGroundType().
Определю координаты спавна луча, который будет принимать в rays[] данные обо всех коллайдерах
Дальше проверяем все коллайдеры в rays. Изначально был цикл freach(), но из его итерации нельзя выйти, используя break, поэтому я использую цик for():
Теперь напишем тело цикла. Сначала начертим сам наш луч, который будет рендериться только в редакторе:
Четвёртый аргумент- длительность отображения луча в секундах.
Дальше выйду из цикла, если коллайдер- триггер (например, хитбокс врага) или у его GameObject’а нет компонента MaterialProperty:
В противном случае возьму пробу материала, и окрашу систему частиц.
Определение функции GetColorByMaterial():
Готово!
Проблема
У функции Physics2D.RaycastAll() есть проблема- она может возвращать один объект несколько раз, а другие игнорировать. Я спросил на форуме Unity о то,, как можно решить эту проблему, но, что ожидаемо, никто не ответил.
Как попытка исправить это недоразумение, я написал метод MultipleRaycast()- его отличие в том, что он создаёт несколько лучей, каждый из которых сохраняет информацию об одном- первом коллайдере в разных местах.
Спойлер: это не помогло.
GetGroundMaterial() создаёт один луч- всего не более 5 лучей, со сдвигом по x на deltaX * 0.3f, по y на - 0.1f * deltaX на каждой итерации.
Результат работы функции MultipleRaycast(), увы, всё тот же: несмотря на увеличившееся число рейкастов, при попадание в триггер ворона лучи не возвращают крышу.
Костыль
Альтернативное решение- изменить цвет систем цастиц по умолчанию на наиболее часто используемый в игре- когда рейкаст не получает MaterialProperty- частицы рендерятся с последним использованным цветом. Для отладки и полной видимости у себя я установил цвета по умолчанию систем частиц trails- белый, land- черный.
Надеюсь, статья вам была полезна. Если нашли решение, которое полностью устраняет проблемы- прошу написать в комментарии. Если интересно читать больше тонкостей разработки- я веду микроблог и ютуб-канал, где рассказываю о разработке игр.