Разработка: персонажи и аниматор
Ровно год назад я рефакторила префабы персонажей, для того чтобы узнать много нового про аниматор, и в конце концов, совсем отказаться от него.
В прошлый раз я добивалась целей:
- Снизить количество вложенных в префаб объектов.
- Снизить количество контроллеров анимации.
- Навести порядок в папках с изображениями.
- Сделать единое позиционирование изображений мимики.
- Исправить «залипание» на последний проигранной анимации.
![](/project/2599/post/36925/image/72461/imagesprojects5992599wxcpio3603j83ae9_original.webp?1689854108434)
Та архитектура была неплоха, я узнала много про оверрайд спрайты, про работу со слоями, про задержки и многое другое. Но эта сложная стейт машина оказалась излишней для моего проекта.
Аниматор очень хорош, когда в игре нужны интерполяции, с плавным переходом из одной картинки в другую. Очень классно, если речь идёт об анимациях персонажа, которым управляет игрок. Взять например, любой 2D платформер, где ветви анимаций и их зависимости выстраиваются единожды, и обеспечивают мягкий переход из состояния в состояние.
В "Тенебре" есть лишь один случай плавного перехода из состояния в состояние, когда персонаж меняет позу. Я это реализовала через дублирование изображения. Под слоем с фигурой персонажа, есть ещё один точно такой же слой, и он включается в тот момент, когда на верхний подаётся новое изображение. Потом он плавно затухает, создав эффект шлейфа, и по завершению принимает новую, актуальную картинку.
![](/project/2599/post/36925/image/72463/imagesprojects5992599i1cpq33603j84d8c.gif?1689854117448)
Немного о том, как это выглядит под капотом:
![](/project/2599/post/36925/image/72464/imagesprojects59925991k4xzk3603j865d2.webp?1689854130335)
Но главная причина, по которой я отказалась от готового решения, это переход на хранение ассетов в adressebbles бандлах. В файле с основной сборкой игры будут лежать только изображения используемые для интерфейсов: рамки, заглушки, иконки, кнопки и т.д.
Весь контент, который относится исключительно к сюжету, теперь убран в адрессеблы и подгружается оттуда только по запросу. Это изображения персонажей, фоны, иллюстрации, музыка, звуки, озвучка.
Но в аниматор нельзя положить адрессебл изображение, а значит при его использовании, в игре будет дублироваться много изображений. Они будут храниться и в основной сборке, и в адрессеблах. Отказавшись от стейт машины, я решила эту проблему. И не только её. Сборка персонажей стала в разы проще, гибче, удобнее и быстрее. Я всё ещё прокидываю вручную много зависимостей, но их стало в разы меньше.
![](/project/2599/post/36925/image/72465/imagesprojects5992599mn4zob3603j8a981.webp?1689854163830)
![](/project/2599/post/36925/image/72466/imagesprojects59925990ey3ap3603j8ajg0.webp?1689854167987)
Это весь код, который мне потребовался, чтобы реализовать анимацию глаз и речи. Через Update в центральном контроллере, каждый фрейм происходит проверка bool значения, предусмотрена ли вообще анимация в данный момент, а потом проверяет на то же bool играет ли она сейчас или уже закончилась и её требуется повторить.
Количество префабов с персонажами было сокращено с 20 (у каждого единовременно работал аниматор, даже в скрытом состоянии) до 3-4. Скорее всего размещу четыре, потому что на сцене как правило находится не более трёх персонажей, а один будет запасным для рокировок при режиссуре.
И немного об устройстве префабов в данный момент:
![](/project/2599/post/36925/image/72467/imagesprojects5992599h3bjqx3603j8c06c.webp?1689854176204)
Character - основной контроллер персонажа, который получает и обрабатывает информацию извне. Обычно, это набор индексов. Ещё он управляет координатами и размером префаба.
Sprites - в нём находится свитчер/переключатель, который управляет слоями с изображениями. Внутри него хранятся SO с персонажами и их характеристиками. Это набор циферных, строчных и булевых значений, собранных в листы.
Body - четыре слоя, рассчитанные на две формы персонажей. У нас есть спрайты 2к на 4к, а есть 4к на 4к. Через bool проверку, свитчер включает или отключает нужные слои, поскольку менять размер картинки напрямую - это очень рискованно и ненадежно. Можно испортить префаб.
Confuse, Eyesm Brows, Mouth, Specific - это небольшие слои для отрисовки разнообразной мимики.
Scriptble Objects:
![](/project/2599/post/36925/image/72468/imagesprojects599259930vhj63603j8d6ai.webp?1689854186685)
Внутри SO с персонажем лежат три списка:
- SO с позами персонажа.
- SO со списками анимаций для глаз и губ.
SO с позой:
![](/project/2599/post/36925/image/72469/imagesprojects5992599lctd2v3603j8e567.webp?1689854194193)
SO со слоями для позы:
![](/project/2599/post/36925/image/72470/imagesprojects5992599q2ckil3603j8f6eh.webp?1689854202763)
SO с айдишниками для анимации:
![](/project/2599/post/36925/image/72471/imagesprojects59925995intuz3603j8g496.webp?1689854209854)
На последнем стриме эту систему верно назвали "конструктором", потому что персонаж собирается из кусочков. Это даёт большую гибкость при конструировании префабов и при режиссуре.
И мне придётся переделывать всю демку, потому что у нас очень сильно изменилась индексация.
![](/project/2599/post/36925/image/72472/imagesprojects59925990sxfht3603j8h5eh.webp?1689854218363)
- Раньше не было индекса под названием Prefab, потому что у каждого персонажа был свой собственный шаблон, с персональным аниматором.
- Не было слоя Red или Confuse. Это небольшая картинка, которая отрисовывается поверх лица, но под мимикой. Это кровь, румянец при смущении. Благодаря этой картинке, удалось избавиться более чем ста больших изображений.
- Я добавила индекс Rotate, чтобы зеркалить префабы. Это иногда нужно при постановке кадра. Совсем не годится для асимметричного дизайна персонажей, но безумно важно для проходных персонажей, у которых мало спрайтов.
- Появился индекс Shader, который работает нифига не через шейдер. Он просто плавно затемняет все слои персонажа, чтобы показать лишь силуэт. Раньше я сохраняла отдельные картинки для каждого такого случая, потому что внедрять новый индекс посреди полуготового проекта - это накладно. Слишком много таблиц требовалось переписать вручную.
![](/project/2599/post/36925/image/72474/imagesprojects59925991zjr0g3603j8j2g0_original.webp?1689854233191)
Всё это я сделала за две недели ежедневной работы часов по 12. Переписала логику, реализовала в движке, изучила много новой информации, собрала большую часть персонажей. Осталось совсем чуть-чуть и можно будет взяться за аватары. Им требуется отдельная логика, значительно отличающаяся от полноростовых персонажей.
0 комментариев