Дамаг виден на весь экран со звуком + есть аптечка
Вчера поработала с окном гардероба.
- Для фона решила взять новое изображение, которое недавно нарисовала для кулона Беатрис. Оно хорошо подходит из-за круглой формы, которую используют практически во всех тайтлах, которые я посмотрела в качестве референсов.
- Основной цвет взяла сиренево-розовый, т.к. он ощущается достаточно спокойным, дружелюбным и на его фоне хорошо читается сама Беатрис, в любом из её нарядов.
- Решила убрать рамку, т.к. она создаёт проблемы с геометричностью элементов и сужает пространство.
- Добавила скроллбар, который можно переключать вручную или воспользоваться колёсиком мыши, чтобы приблизить/отдалить фигуру Беатрис.
- При скролле, Беата всегда центрируется по верхнему краю.
Пришлось немного нарушить правила и написать в классе Update, чтобы сделать окно максимально самобытным. Хотя, в данный момент это решение временное, потому что мне в любом случае нужно будет прокидывать связи к этому классу из других, чтобы модели знали о новой переменной одежды, выбранной игроком.
С 14 июня я плотно занимаюсь переработкой проекта.
В течение пары дней я перенесла проект с версии Unity 2020 на 2022, восстановила все ассеты, обновив их до актуальных версий и отказавшись от неподдерживаемых. Создала отдельную сборку, в которую скармливаю гугл-таблицы, чтобы из них парсить итоговый JSON и не хранить ничего лишнего в основном проекте. Сохранила старые интерфейсы в виде префабов для дальнейшего улучшения.
С 16 по 28 июня я занималась обновлением вёрстки основных интерфейсов, переписывала поведение кнопок, их отклик, собирала небольшие изображения в атласы и документировала все изменения, чтобы QA специалистам было проще тестировать новую сборку. Были готовы следующие интерфейсы:
- Дисклеймер (добавлена смена локализации)
- Стартовое меню (добавлена информация о прогрессе игрока и версии сборки)
- Боковое меню основного экрана.
- Текст-бокс (реализованы подсказки при наведении на кнопки интерфейса, объясняющие их функции)
- Смартфон и его экраны.
- Логи (добавлено меню с репутацией персонажей)
Связала все эти меню, чтобы между ними можно было переключаться. Задала позиционирование всем подвижным интерфейсам.
29 июня - подготовила новую структуру гугл-таблиц из которых воспроизводится вся игра.
3-9 июля были посвящены настройкам. Поиск нового дизайна, вёрстка экранов, замена кривых скроллбаров на слайдеры, работа с откликом панелей настроек, реализация функций, вроде локализации, изменения громкости разных источников звуков, сохранения настроек в специальный файл, его создания и чтения при запуске игры. Так же, проверила все используемые изображения в проекте, их настройки, собрала в атласы и т.д.
10 июля - реализация подсказок, которые будут воспроизводиться во время игры, при изменении репутации отношений с кем-то из персонажей.
11 июля - реализация карты маршрутов, чтобы игрок мог увидеть прогресс в различных сюжетных нодах.
С 12 по 17 июля я занималась контроллерами для отрисовки персонажей. Это сложный конструктор, содержащий много слоёв, с вариативностью под разные размеры исходных изображений с персонажами, с зацикленными и обрывающимися анимациями. Реализовано несколько удобных функций, которых мне не хватало в прошлой сборке. Все изображения персонажей перенесены в Addressables. Переписан инструмент реализованный через Editor.
С 17 по 20 июля - сборка единого универсального префаба для всех персонажей, в котором хранятся SO со ссылками на изображения в Addressables, которые будут загружаться исключительно по запросу.
С 21 по 30 июля - реализация подобных скриптов для аватаров. Сборка аватаров для девяти персонажей.
Планы на август (+):
- Реализация выведения таблиц в игре, основные механики переключения фреймов и сцен.
- Вёрстка обновлённого меню сохранений и их новая реализация.
- Реализация подсчёта прочитанного текста и выведение этой информации.
- Реализация окна с концовками.
- Доработка смартфона.
- Галерея с артами.
- Галерея с персонажами.
- Механика переодевания главной героини.
- Поддержка контроллера и добавление ещё одного окна в меню настроек для переназначения клавиш.
- Проверка состояния интерфейсов, чтобы управлять ими через горячие клавиши не создавая конфликтов.
Ровно год назад я рефакторила префабы персонажей, для того чтобы узнать много нового про аниматор, и в конце концов, совсем отказаться от него.
В прошлый раз я добивалась целей:
- Снизить количество вложенных в префаб объектов.
- Снизить количество контроллеров анимации.
- Навести порядок в папках с изображениями.
- Сделать единое позиционирование изображений мимики.
- Исправить «залипание» на последний проигранной анимации.
Та архитектура была неплоха, я узнала много про оверрайд спрайты, про работу со слоями, про задержки и многое другое. Но эта сложная стейт машина оказалась излишней для моего проекта.
Аниматор очень хорош, когда в игре нужны интерполяции, с плавным переходом из одной картинки в другую. Очень классно, если речь идёт об анимациях персонажа, которым управляет игрок. Взять например, любой 2D платформер, где ветви анимаций и их зависимости выстраиваются единожды, и обеспечивают мягкий переход из состояния в состояние.
В "Тенебре" есть лишь один случай плавного перехода из состояния в состояние, когда персонаж меняет позу. Я это реализовала через дублирование изображения. Под слоем с фигурой персонажа, есть ещё один точно такой же слой, и он включается в тот момент, когда на верхний подаётся новое изображение. Потом он плавно затухает, создав эффект шлейфа, и по завершению принимает новую, актуальную картинку.
Немного о том, как это выглядит под капотом:
Но главная причина, по которой я отказалась от готового решения, это переход на хранение ассетов в adressebbles бандлах. В файле с основной сборкой игры будут лежать только изображения используемые для интерфейсов: рамки, заглушки, иконки, кнопки и т.д.
Весь контент, который относится исключительно к сюжету, теперь убран в адрессеблы и подгружается оттуда только по запросу. Это изображения персонажей, фоны, иллюстрации, музыка, звуки, озвучка.
Но в аниматор нельзя положить адрессебл изображение, а значит при его использовании, в игре будет дублироваться много изображений. Они будут храниться и в основной сборке, и в адрессеблах. Отказавшись от стейт машины, я решила эту проблему. И не только её. Сборка персонажей стала в разы проще, гибче, удобнее и быстрее. Я всё ещё прокидываю вручную много зависимостей, но их стало в разы меньше.
Это весь код, который мне потребовался, чтобы реализовать анимацию глаз и речи. Через Update в центральном контроллере, каждый фрейм происходит проверка bool значения, предусмотрена ли вообще анимация в данный момент, а потом проверяет на то же bool играет ли она сейчас или уже закончилась и её требуется повторить.
Количество префабов с персонажами было сокращено с 20 (у каждого единовременно работал аниматор, даже в скрытом состоянии) до 3-4. Скорее всего размещу четыре, потому что на сцене как правило находится не более трёх персонажей, а один будет запасным для рокировок при режиссуре.
И немного об устройстве префабов в данный момент:
Character - основной контроллер персонажа, который получает и обрабатывает информацию извне. Обычно, это набор индексов. Ещё он управляет координатами и размером префаба.
Sprites - в нём находится свитчер/переключатель, который управляет слоями с изображениями. Внутри него хранятся SO с персонажами и их характеристиками. Это набор циферных, строчных и булевых значений, собранных в листы.
Body - четыре слоя, рассчитанные на две формы персонажей. У нас есть спрайты 2к на 4к, а есть 4к на 4к. Через bool проверку, свитчер включает или отключает нужные слои, поскольку менять размер картинки напрямую - это очень рискованно и ненадежно. Можно испортить префаб.
Confuse, Eyesm Brows, Mouth, Specific - это небольшие слои для отрисовки разнообразной мимики.
Scriptble Objects:
Внутри SO с персонажем лежат три списка:
- SO с позами персонажа.
- SO со списками анимаций для глаз и губ.
SO с позой:
SO со слоями для позы:
SO с айдишниками для анимации:
На последнем стриме эту систему верно назвали "конструктором", потому что персонаж собирается из кусочков. Это даёт большую гибкость при конструировании префабов и при режиссуре.
И мне придётся переделывать всю демку, потому что у нас очень сильно изменилась индексация.
- Раньше не было индекса под названием Prefab, потому что у каждого персонажа был свой собственный шаблон, с персональным аниматором.
- Не было слоя Red или Confuse. Это небольшая картинка, которая отрисовывается поверх лица, но под мимикой. Это кровь, румянец при смущении. Благодаря этой картинке, удалось избавиться более чем ста больших изображений.
- Я добавила индекс Rotate, чтобы зеркалить префабы. Это иногда нужно при постановке кадра. Совсем не годится для асимметричного дизайна персонажей, но безумно важно для проходных персонажей, у которых мало спрайтов.
- Появился индекс Shader, который работает нифига не через шейдер. Он просто плавно затемняет все слои персонажа, чтобы показать лишь силуэт. Раньше я сохраняла отдельные картинки для каждого такого случая, потому что внедрять новый индекс посреди полуготового проекта - это накладно. Слишком много таблиц требовалось переписать вручную.
Всё это я сделала за две недели ежедневной работы часов по 12. Переписала логику, реализовала в движке, изучила много новой информации, собрала большую часть персонажей. Осталось совсем чуть-чуть и можно будет взяться за аватары. Им требуется отдельная логика, значительно отличающаяся от полноростовых персонажей.
Unity предоставляет несколько способов хранения контента:
- Общая папка Assets, из которой в билд уходят используемые на сценах компоненты.
- Папка Resources, которая билдится в игру целиком, а объекты подгружаются запросом по имени и типу контента.
- Папка StreamingAssets, в которой контент никак не пакуется и отдаётся в чистом девственном виде - как есть (пока не знаю примеров его использования, но думаю на тему использования для сейвов, в жёстко закэшированной папке)
- Addressables, которые пакуются в самостоятельные бандлы и позволяют подгружать этот контент даже по сети.
В первом случае, я храню всё что используется для интерфейса игры.
От второго - я сейчас всеми правдами и неправдами избавляюсь. Проблема в том, что эта папка билдится очень тяжёлой. Обращение по именам - это опасно, потому что я могу изменить структуру папок или названия файлов. И код придётся переписывать. А если поместить эти объекты прямо в поля объектов на сцене или в используемые Scriptable objects, все компоненты тут же потянутся в оперативку при загрузке сцены. Это замедляет загрузку игры, а так же вынуждает потреблять оперативную память для редко используемых комполнентов.
Ещё один нюанс такого решения - это сборка из большого и тяжёлого моно файла, что является большой проблемой для веба и мобайла. Они обычно ограничены 25Мб на один файл. В будущем я планирую порт, да и сборка в вебе, которую тут же можно дать потыкать с планшета - это безумно удобно и хорошо работает на конверсию вовлечённой аудитории.
Последний вариант с адрессеблами позволяет разбить большой файл на небольшие бандлы, вес которых я могу контролировать. Кроме того, можно хранить прямые ссылки в объектах, но контент не будет сразу подгружаться в игру, если те размещены на сцене. Подгрузка происходит только по прямому запросу из кода.
Я уже организовала новую структуру и логику хранения изображений для персонажей, а так же способы их отрисовки. Ресёрч и работа заняли меньше недели, но у меня появились новые проблемы, которые подводят к отказу от базового аниматора из коробки.
Подробнее расскажу в следующей статье.
Обычно, такого в визуальных новеллах не делают. По крайней мере я, моя команда и активные подписчики, подобного нигде не видели. Как правило всё ограничивается галереей с иллюстрациями и списком концовок. Если что-то осталось закрыто, значит есть ещё контент для чтения.
Мне захотелось пойти дальше и визуализировать ветвление не только в презентациях, но и в интерфейсе игры. Здесь отображены глобальные сюжетные ноды и концовки. Прогресс будет заполняться в зависимости от данных в специальном файле на ПК юзера, где ведётся учёт ранее прочитанных фреймов.
Последние трое суток, сильно страдая от бессонницы, я перебрала систему парсинга данных из гугл таблиц в удобные JSON файлы. Из-за того что я решила переверстать все меню и улучшить системы, которые отвечают за сборку игры, мною было принято решение переписать и парсинг. Хотелось, чтобы сборка игры в таблицах была удобнее, чтобы я могла дробить одну сцену на логические блоки и в таблице с сюжетом указывать, нужно ли в следующем фрейме изменить воспроизводимый блок или сцену.
Наверное, я сложно объяснила. Если проще, это необходимо для удобного ветвления сюжета. Оно и раньше отлично ветвилось, но мне приходилось ссылаться на другие таблицы, чтобы выполнять проверки, всегда следить за количеством фреймов которые надо пропустить и т.д. Теперь всё будет в одной таблице и довольно лаконично.
На этом шаблоне я сегодня уже оттестировала работу скрипта, который старательно писала в отдельном приложении. Этот код со всеми ссылками на гугл таблицы, не войдёт в билд игры. Он нужен лишь для того, чтобы создать несколько текстовых файлов, которые я бережно помещу в финальную сборку. Так я избавляюсь от лишних компонентов в игре, паранойи, что кто-то при декомпиляции найдёт ссылки или я случайно не удалю черновые файлы.
Сейчас уже реализованы:
1. Лист переменных для отслеживания взаимоотношения с персонажами.
2. Словарь имён игровых персонажей с учётом поддерживаемых языков.
3. Список звонков и сообщений для смартфона.
4. Список доступных в игре выборов.
5. Список доступных концовок.
6. Список индексированных сцен.
Чем я пользуюсь:
1. Google sheet to Json - сохраняет гугл таблицы в текстовых файлах. Под каждый лист создаёт отдельный файл, в соответствии с его названием.
2. LitJson Ruler - очень простое решение, чтобы читать и записывать JSON файлы. Мне было важно, особым образом пересохранять данные таблиц, чтобы потом форматировать их в иную JSON структуру под проект. Например, в таблице русская и английская локаль, находятся в разных колонках. Это важно, чтобы не перемешивать данные, контролировать количество знаков в тексте, не запутаться в экранирующих символах и удобно читать сценарий. В то же время, в JSON они должны находиться в одном разделе как набор строк. Оттуда, игра уже по индексу берёт текст на выбранном языке.
Я очень довольна тем, что скрипты стали лаконичными, что у проекта появилась чёткая логика, он стал легковесным и сущности между собой не переплетаются.
Да, морально мне тяжело даются переработки уже готового материала, но всё это явно стоит приложенных усилий. После трех недель довольно плотной работы, надо устроить себе игровые выходные. Я как раз купила себе Сабнавтику.
Вчера мучилась бессонницей до 7 утра, а может и дольше. Что-то не так с эмоциональным фоном в последние дни. Или последние недели. А если точнее, то последние полгода. Разработка постоянно растягивается на всё более необозримые сроки, а фидбека от команды всё меньше. Людям хочется видеть результат. Что игрокам, что разработчикам.
Да, всё именно так. Даже у самых мотивированных, позитивных, прущих на пролом и уверенных в себе, бывают минуты слабости. И продолжительные состояния подавленности, апатии, ощущение "дня сурка". Единственное, что нас отличает - мы всё равно ищем возможности, чтобы продолжать.
Коротко о первой половине недели:
Я снова подалась на конкурс концептов. В этот раз его проводит Индимейкер. А конкурсная работа - это концепт для следующей игры. Он открытый, его можно почитать.
Я закончила базовую связку между интерфейсами. То есть, создала шаблоны окон и объяснила приложению (да, мы программисты, говорим со своим проектом при помощи кода), какие окна должны открываться, если нажимаются те или иные кнопки. Никакой сложной связанности, компоненты не знают друг о друге и ими управляет главный контроллер, отвечающий за отрисовку вьюшек.
Порядок важен вокруг. Порядок нужен в планировании. Порядок нужен внутри проекта. И порядок нужен в голове. Вчера был больше терапевтический день. Немного нытья в геймдев чатиках, немного работы с тряпкой, немного новых досок в WeeeK, несколько часов плотной работы с таблицами, и поиск ответов на вопрос: что именно меня угнетает. Поиск причины - это первый шаг к излечению.
Про обновление таблиц расскажу потом в платных постах. Что было важно переделать, и как из них собирается игра.
Мне очень нравится вёрстка. За день мне удалось довести до ума наш текст-бокс и начать работу со смартфоном. Если телефон я ещё не готова показывать, поскольку работа больше шла в структуре слоёв и с заменой иконок. А вот текст-бокс получился хорошим.
Стало:
Было:
Что в итоге сделано:
- Откалибровано позиционирование элементов интерфейса.
- Обновлены боксы для смартфона.
- Полностью изменены кнопки.
Состояния кнопок:
- Обычное состояние: без цветного фона, без обводки.
- Наведён курсор: цветной фон, но без обводки.
- Нажатая кнопка (активная): цветной фон и обводка.
- Неактивная кнопка: без цветного фона, без обводки, иконка серого цвета. Применительно только для двух верхних кнопок из-за их специфики.
За день купила два ассета в магазине Unity, в которых собрано большое количество векторных элементов для UI.
В одном паке много красивых бэкграундов нарисованных текстурными кистями. Очень подходит под наш стиль. Бежевый контур для кнопки взят как раз оттуда.
Во втором паке много иконок: стрелочки, настройки, клавиши, логотипы социальных сетей в одной стилистике.
Очень горжусь стилизованной панелькой с подсказками о функциях кнопок. Далёкое от визуальных новелл комьюнити, совершенно не понимало, что они обозначают. Те кто имеет опыт игры в этом жанре, тоже порой путаются.
Мне не хотелось делать обучение, которое знакомит с функциями кнопок и интерфейсов. Это затягивает момент наступления начала игры, что весьма плохо. Да и вдруг человек забудет, о чём ему рассказывали. Подписывать сами кнопки мне тоже не хотелось, чтобы исключить лишние тексты из интерфейса. А это решение, кажется мне компромиссным и элегантным.
Панель появляется лишь при наведении курсора на кнопки. И пропадает, если курсор не наведён. Стало очень стилёво.
В конце дня, обновила документацию по текст-боксу, чтобы будущим QA было понятно, что именно требуется тестировать.
Выжимка последних двух дней: продолжаю заниматься интерфейсами и поведением кнопок, а параллельно, обдумываю план по облегчению экспозиции в сюжете.
Не то чтобы я сегодня была продуктивной, но над проектом немного поработала. Переписала логику поведения кнопок в стартовом меню игры, анимировав фон через DOFillAmount. Записала небольшое видео с анимацией:
Сегодня я сделала первые шаги к переработке проекта.
Нет, всё не настолько отчаянно, как я это описывала вчера. Я перенесла весь проект на новую версию движка, чтобы не переделывать с нуля вёрстку. Удалила все скрипты, потому что в версии 2022 отличается синтаксис, да и код нужно переписывать...