М А Я К: Devlog #2. Подробный рассказ о разработке
В тексте возможны спойлеры, поэтому если вы еще не играли и хотите получить «чистый» экспириенс, то к тексту лучше вернуться после игры.
Перед тем как рассказывать непосредственно о разработке проекта предлагаю вернуться к началу джема и поговорить об игровой задумке.
Как я писал в прошлом DevLog еще до объявления темы мы поставили себе парочку майлстоунов. В этот раз стоит их перечислить:
- Хотелось попробовать реализовать квестовую систему 💔
- Сделать инвентарь ☑️
- Сделать полную поддержку геймпада 💔
- А так же цели чисто для меня:
- Набить руку в стилизованной графике ☑️
- Освоить уже наконец-то процедурное создание текстур в Substance Designer ☑️
- Освоить создание разных деревьев ☑️
- Освоить анимацию в Cascadeur 💔
- Попрактиковаться в работе с trim sheet’ами ☑️
Изначально игра виделась чем-то вроде Minit, или The Legend of Zelda: the links Awakining, но потом была объявлена тема, и мы немножко потерялись. Идей было много: от симулятора быстрых свиданий, до темы хороший/плохой коп и даже ремейка моей старой игры на 15ый гаминатор. В итоге общим голосованием мы решили делать М А Я К.
По первоначальной задумке игра включала в себя плюс-минус все, что получилось в итоге, но с другими приоритетами и акцентами. Это должно было быть сюжетное приключение с элементами метроидвании и выживача.
Герои должны были найти несколько деталей механизма маяка. Локации бы открывались постепенно, в зависимости от текущих квестов и найденных предметов (например, чтобы спуститься в логово рыболюдов, нужно было найти веревку и крюк). Планировалась глобальная карта острова, где бы помимо расположения локаций игрок бы наглядно получал информацию о текущем времени игровом времени и мог проще планировать длину маршрута. Возможно, так же был бы перевалочный пункт, где можно было бы переждать ночь, не возвращаясь в маяк. Смотритель маяка играл бы более важную роль, не просто декорации влияющей на экономику игры, но и собеседника-квестодателя. Соответственно лор выдавался бы постепенно, а не вываливался плотным потоком в первом же диалоге. Собирать ресурсы и менеджерить второго брата нужно было бы больше ради баффов и избегания дебаффов. Это не должно было быть самоцелью. Более того брата можно было бы брать с собой чтобы решать ряд задач. Планировалось, что некоторые локации можно проходить свободно переключаясь между братьями, что помогло бы решать те или иные задачки.
Пример такого можно встретить в самом начале игры, где один герой должен пролезть под завалом, чтобы сбросить ствол дерева, по которому сможет залезть старший брат.
Звучит грандиозно? Было вполне ясно, что этот план порежется, как это всегда и бывает. На то и расчет, никогда заранее не знаешь как пойдет разработка и куда оно повернет, поэтому план должен быть адаптивным, но иметь всегда какую-то цельную картину, на которую можно ориентироваться. Но камнем преткновения стало сложность реализации ряда вещей и некоторые жизненные обстоятельства, которые не позволили довести до ума ряд аспектов. Чисто системно, почти все указанное выше было сделано, кроме, разве что, квестовой системы. Однако не все попало в игру. Например, диалоговая система в финальной игре запускается через триггеры, хотя механика «подойти к персонажу нажать взаимодействие и поговорить с ним» была реализована, даже нюанс, чтобы диалог после повторного посещения персонажа не повторялся был учтен. Так же под нож пошли из почти готового такие штуки: просвечивающиеся стены вокруг персонажа, система нокаутов для игрока и врагов, визуальные приколюхи, свободное переключение между персонажами
Система нокаутов работает по типу того как работает падение с высоты, если не убился то можно встать. В этом был нюанс разных оружек. Сабля больно бьет, но дубина, хоть бьет значительно менее больно, но оглушает и роняет врагов. Таким образом можно было осуществлять краудконтроль
В этот раз я впервые за долгое время участвуя в гаминаторе еще и исполнял роль программиста, и написал существенную часть кода. Поэтому я буду более подробно говорить за ряд систем которые реализовывал сам, ибо далеко не во всем, что писал Дима, у меня было время разбираться.
Геймплей и игровые системы
Как я писал ранее начали мы с темплейта third person controller в Unity. На который начали навешивать разные фичи.
- Персонаж умеет переходить в рэгдол и обратно, нужно например для падения с высоты. У персонажа рассчитывается его velocity, и если она превышает определенный порог то в момент соприкосновения с поверхностью включается рэгдол, добавляется накопленная velocity в костям и персонаж корректно отлетает, после чего (если не умер) встает и может идти дальше. Тут почти все получилось хорошо, за исключением, того что оно иногда багует и персонаж вместо того чтобы корректно встать с того места где лежал немного разворачивается, и что велосити почему-то назначается по направлению forward, что приводит к забавной картине при падении с большой высоты вертикально вниз, вместо того чтоб сильно ударится о землю и подлететь, он улетает в сторону.
- Передвижение на 4 конечностях всегда гемор, в данном случае тоже, когда мелкий парень ползет на четвереньках можно по идее стоять на обрыве и чтобы руки опирались как бы на воздух, нам это показалось странным, и в игре реализована штука, которая рейкастит вниз из груди персонажа и если там ничего нет, то он падает. Передвигаясь на четвереньках персонажа хуже замечают враги, в кустах же его вовсе не видно, но если его уже заметили, то там просто там не спрячешься.
- Аниматор имеет два слоя отвечающих за нижнюю и верхнюю части тела. Это позволило осуществить бОльший контроль над движениями персонажа, особенно для старшего пацана, который умеет драться.
Боевую систему мы хотели сделать крайне простой, планировалась еще какая-нибудь реализация таргет лока, но руки до этого не дошли.
Изначально факел, должен был быть предметом, который кладется в левую руку вместо щита. Так как планировались темные пещеры, у вас бы появлялся геймплейный выбор ходить с факелом и все хорошо видеть, либо же доставать щит и быть более защищенным, но тогда приходилось бы мериться с темнотой, либо выманивать врагов на более освещенные участки. Но когда во время разработки начали возникать проблемы с инвентарем и системой предметов от этого отказались, а щит оказался особым предметом который не помещается в инвентарь (кто-то может вспомнить аптечку, которую нужно взять по сюжету, но она технически просто интерактивный объект как и ствол дерева на пляже). Так же факел или его аналог должен был быть у пацана, в какой-то момент даже была идея добавить ему «мистических сил» и чтобы он мог лучше видеть в темноте, слышать врагов как в TLOU.
Система смены времени суток оказалась довольно простой в реализации, но и здесь возникли подводные камни. Мы использовали Universal Render Pipeline, и как оказалось, он не умеет в тени от двух direction light source одновременно. Пришло изобретать костыли и вылезли косячки, которые ме не до конца починили в итоге. Например, луна как источник света по началу вовсе выключена, на заходе солнца она включается и начинает крайне слабо светить (к сожалению, это включение очень сильно заметно, даже не смотря на нулевую интенсивность луны в этот момент (хотя пока я пишу эти строки понимаю, что это может быть совсем не так и нужно проверить этот момент, в момент разработки эта проблема была наименее приоритетной, поэтому руки не дошли)). Затем когда полностью смеркается солнце выключается, и начинает работать корутина, которая плавно поднимает shadow strenght с 0 до 1 в течении нескольких секунд.
Динамическая аудиосистема должна была отвечать следующим требования: отражать время суток, оповещать о врагах и добавлять атмосферы конкретным локациям. Последнее требование в процессе разработки не было выполнено. Изначально планировалось, что каждая локация в игре будет отдельной сценой, и там будет свои дубликаты систем, в том числе MusicManager. В итоге я бы просто проставил в каждой локации свои мелодии и было бы как нужно. Но ближе к концу разработки когда начали возникать проблемы с переносом прогресса между сценами, сохранением и прочим, было принято решение объединить все сцены в одну, поэтому саундтрек на всех локациях одинаковый, а допиливать систему времени не было. Система в целом получилась хорошей, но иногда музыка играет немного невпопад, но это вина других систем, которые некорректно взаимодействуют с музыкальным менеджером.
Диалоговая система основана на плагине Dialogue System for Unity. Его я уже использовал при разработке своей небольшой игры год назад. Плагин очень мощный, хоть и не без проблем. Его использовали, например, в отечественной Black Book. В моей «учебной» игре, о которой я писал тут, переключение диалогов было крайне примитивно сделали, тут же мы реализовали их инициацию как после разных действий (вхождения в триггеры, интеракции с объектами, разрушение некоторых объектов) так и как в RPGшках, когда ты можешь подойти в любому персонажу и заговорить с ним. Последнее было вырезано, но вот пруфы:
Еще планировалось, что каждая фраза будет обрамляться соответствующим настроению фразы звуком, хотел даже привлечь людей на озвучку, но отказались от этой затеи в связи с нехваткой времени.
ИИшка тут довольно хитрая и имеет несколько слоев. Основана она на том, что я делал в сентябре для одного своего проекта, но здесь ее пришлось адаптировать и всячески допиливать.
Каждый враг сам по себе автономен и имеет несколько основных состояний: патрулирование, преследование, поиск и несколько технических: спавн, деспавн, смерть. Помимо этого каждый рыболюд связан с локальной руководящей системой. Она в свою очередь связана со всеми дочерними рыбюлюдами, циклом дня и ночи, а так же аудио менеджером. Каждая такая система имеет определенную зону, где она активна, и запускается как только игрок вступает в эту зону. В этот момент происходит команда на спавн. Когда игрок покидает зону, рыболюды уходят на точки деспавна, однако если определенный рыболюд в данный момент преследует игрока, или ищет его, то он не уйдет на спавн, пока не перейдет в спокойную фазу. Так же рыболюды умеют оповещать друг друга об игроке через специальный рык, который через родительскую систему связывается с другими рыболюдами из конкретной области. Получив такой сигнал сородичи отправятся в точку где находился игрок в момент рыка рыболюда и перейдут в состояние поиска. Состояние поиска так же запускается когда рыболюд преследующий игрока теряет его из виду, в этом состоянии враг начинает патрулировать зову в определенном радиусе, после чего спустя таймер он возвращается к своему спокойному состоянию.
Когда рыболюд замечает игрока, он обращается в родительскую систему, и та триггерит нарастающий звук, как только порог превышен, проигрывается impact звук обнаружения, после чего триггерится преследование и музыка сражений. Система в целом похожа на аналогичную в The Last of Us, но работает кривовато. У Unity какие-то траблы с рейкастами и определением коллизий, еще когда делали Метаинститут заметили, что враги на другой стороне комплекса триггерятся на игрока. а проблема в тестах выяснилась в том, что иногда что-то где-то пролагивает, и луч стреляет сквозь коллизии. Я долго думал как это чинить, пробовал всякие spherecast’ы вместо raycast, но тщетно. В итоге пришел к тому, что засчитываю попадание лучем, только спустя несколько попаданий подряд, чтобы случайные попадания не триггерили врагов.
Еще враги получились очень анимационно зависимыми, в этом их достоинства и одновременно недостатки, ибо для корректной работы и интересного поведения требуются хорошие rootmotion анимации, забегая вперед скажу, что среди персонажных анимаций в проекте всего одна моя, остальное с mixamo и одного плагина, а там анимации откровенно не очень. Еще я прикрутил к ним визуальное отображение урона (как и к главным героям и разрушаемым объектам), но про это тоже ниже.
Очень хотелось сделать так, чтобы в игру можно было спокойно играть с геймпада, и к сожалению, это выполнено лишь на половину. В целом все отлично работает, кроме менюшек и инвентаря. Настроить чтобы все правильно выбиралось и перескакивало между менюшками, по словам Puffick, оказалось геморно, и под конец разработки мы уже не стали запариваться, но в остальном играется с геймпада хорошо.
Геймплейный луп во многом схож в Darkwood, концепция ночных нападений взята от туда, но упрощена до чистой математики. Сперва на первом экране вы смотрите все текущие состояния, тут же баррикадируете дом если нужно. Затем выводится лог событий за ночь. Событий может быть три: «ничего не произошло», «напал маленький отряд рыболюдов», «напал большой отряд». В первом случае герои просто кушают на ночь и отдыхают. Если провиант закончился то накладывается дебафф на выносливость. Если же рыболюды нападают на вас, то последствия рассчитываются в зависимости от того как много баррикад осталось у вас после получения ими урона от кол-ва врагов. Есть два нижних лимита, которые определяют последствия. Вы получаете урон, дед получает урон, определенное количество ресурсов у вас воруют. Дед же играет не только декоративную функцию, но и дает бафф к ремонту маяка, а так же требует провиант. Его жизнь можно поддерживать уделяя время на его лечение, плюс благодаря зельям лечения, которые можно создавать из специальных ягод, которые может находить только младший брат.
Графика
Вся графика, кроме персонажных анимаций, ui спрайтов (кроме иконок item’ов), модели папоротника и пары текстурок земли, были сделаны с нуля и вручную. Я изначально планировал делать стилизованную мультяшную графику, хотя у меня не было особо много опыта в ней, однако этот стиль дался мне довольно просто, чему я очень рад. Но времени на излишества все равно не было, поэтому местами вышло простенько. Первое чем я занялся занимаясь им это природа.
У меня раньше был травмирующий опыт в создании деревьев для игры. Использовал я для этого SpeedTree, а текстурки для веток и leaveCards абсолютно не понимал откуда брать. В какой-то момент я забил на попытки в деревья и использовал бесплатные/покупные ассеты. Теперь у меня была цель научиться делать круто. Я начал я малого. Сперва я сделал смоделировал листочек, и с его помощью создал вот такую текстурку для листьев.
Затем, научился собирать вот такие шапки с помощью geometry nodes, а также правильно настраивать нормали для вертексов, ибо если это не сделать будет выглядеть отвратно.
Сами же деревья моделю в TreeIt. Эта прога похожа на SpeedTree, только проще и к тому же бесплатная.
но еще и багованная, поэтому если будете тыкать сохраняйтесь почаще
И уже после этого в Blender объединяю с «шапками» из листвы, что намоделил ранее. Анимация для кроны дерева и для самой листвы сделаны с помощью шейдера, уже непосредственно в Unity. Так же для атмосферы добавил опадающие листочки. Красиво!
Трава в игре так же 3Dшная, каждая травинка это несколько изогнутых полигонов, благодаря перспективе получилось поставить очень маленькую дальность ее прорисовки, поэтому она не сильно влияет на производительность. Пока писал этот текст понял, что я же еще цветов наделал, но забыл их добавить, мдеееее… Ну ладно.
Текстуры для террейна в большинстве своем так же сделаны вручную и процедурно с помощью Substance designer. Что позволило быстро делать по несколько вариантов одной и той же текстуры, чтобы скрывать тайлинг и делать ландшафт более разнообразным.
Очень сложно было с персонажами. Я долго думал какой стиль выбрать, важно было чтобы они были простыми, но прикольными. В моем реф. борде было очень много разных вариантов. В какой-то момент я вспомнил про Inside, нашел модельку паренька от туда в интернете, вставил в игру и он стал нажим тестовым персонажем. Решил, что это прям то что нужно.
И да, внимательный читатель заметил дохрена картинок ракшей на борде. Создавая рыболюдам я отсылал к ним, и для более крутых разновидностей я хотел дать в руки посохи как у ракшей, но это тоже пошло под нож /;
Когда я моделирую персонажей обычно я беру болванку из своей коллекции, так куда меньше шанс напортачить с анатомией и скорость создания ускоряется, но для данной игры ни одна из моих болванок не подходила, поэтому я решил смоделить персонажей с нуля, чего не делал очень давно. В итоге получилась прикольная болванка которую очень просто модернизировать, ибо изначально она ну очень лоуполи и сделана специально под SubDiv. Из нее я и сделал трех главных персонажей.
Волосы сделал с помощью кривых, затем все объединил в один текстурный атлас и затекстурил в Substance painter. Получилось клево.
С рыболюдами было сложнее, их я моделил с болванки тела человека, поверх которой уже намоделил рыбью голову. Разворачивал я их тоже под атлас, планировалось 4 варианта раскраски. Так же я хотел, чтобы все они были на одном материале, и с одним набором текстур, поэтому один вариант раскладки UV island’s занимает ¼ всего поля. Затем в шейдере я просто сдвигаю UV на 0.5 в нужную мне сторону.
Для визуального отображения урона используется две системы. Первая — отображение момента получения урона, в этот момент происходит vertex displacement, перекраска base color и emission каналов в белый цвет. Вторая система только для рыболюдов. Я в Substance painter сделал отдельную чб текстуру с кровякой. Ее я использую для изменения цвета, smoothness и перекрытия normal в шейдере. Причем подмешиваю через шум. С каждым ударом по рыболюду его bloodAmount растет с 0 до 1, в зависимости от количества жизней противника. На кадре ниже прям криповенько вышли.
А что не выглядит клево, так это анимации. Изначально я планировал освоить cascadeur и наделать там анимаций. Освоить то я освоил, и даже в работе его начал использовать, но анимаций для игры наделать не успел. Там только одна анимация, это spawn рыболюдов, и то, это была первая версия и я хотел ее переделать. Другие анимации это миксамо, теймплейт unity c которого мы начинали и анимации из купленных ассетов. С последними отдельный рофл. Мы думали до проектирования боевой системы, что вообще возьмем ее из ассета, но когда мы ее потыкали в живую, нам не понравилось, остались только анимации от туда. В оригинале там мощный рыцарь в доспехах, а у нас пацан дрищ, и эти анимации выглядят на нем крайне нелепо. Планировал их заменить, но руки не дошли, в итоге когда он обнажает оружие, то ходит как будто в пятой точке лом застрял. Ужс.
Еще по окружению. Подбираемые айтемы и оружки, сделаны тоже на отдельных атласах, чтобы не плодить в сцене материалы. Камни делятся на два типа, относительно небольшие тоже сделаны под атлас, сперва я замоделил Hi-poly, потом сделал ретопологию и запек текстурки, приправив сверху процедурным самолично сделанным умным handpaint материалом, а другие более большие текстурируются через трипланарный шейдер в самом юнити.
Остальное же окружение все завязано на два trim sheet’a. Их я тоже сперва замоделил в hi-poly варианте, а потом запек в plane, сделал текстуры, потом нарезал и делал модели. Очень клевый метод для быстрого моделирования, к тому же еще и лучше оптимизация получается. Внутри дома так же планировалось больше всего, и как минимум декали, текстуры для них я тоже успел сделать, но до самих декалей руки уже не дошли.
С помощью декаль проджектора и специального шейдера так же сделал динамические тени от облаков, но опять таки руки не дошли воткнуть, эх. Еще был вот такой клевый шейдер, но опять таки не осталось его в игре.
С водой получилось не очень, она конечно визуально реагирует на объекты и рельеф, но никакой интеракции не успели реализовать. Еще она очень не очень с террейнами юнитевскими работает, каждый полигон их видно. Надо было берег отдельным мешем делать.
UI рисовать я не очень умею, да и времени на него тратить не хотелось, поэтому часть я нашел бесплатных штук, которые даже автора помечать не нужно, а часть генерил в playgroundai, а потом уже много фотошопил.
Реализация темы и итоги
Условие конкурса мы выполнили через двух персонажей с чутка разным геймплеем. С темой сложнее. Она довольно абстрактная, и можно по разному ее объяснить: мы взяли реальный сеттинг и наводнили его чем-то фантастическим. Но это скучное объяснение, хотя я реально смотрел документалки про маяки и читал статьи на тему в начале разработки. Так же в игре есть пасхалочка, которая тоже раскрывает тему, но ее я спойлерить тут не буду) Ну и к тому же я решил с вами провести ARG. Но вы скучные, и практически никто не захотел со мной играть, эх вы. Благо есть еще ребятки в моих публичных страницах в соц.сеточках, и они подсобили. В итоге все ограничилось просто дневником смотрителя маяка, который я старался регулярно обновлять. Нет вам прощенья!
В общем не могу однозначно оценить итоги джема для себя. С одной стороны сделали очень много крутых штук, с другой в последний день оказалось, что игра в билде ломается, поэтому множество мелких штук, которые я оставил на последний день пришлось доделывать в багодень, а часть вообще не делать, ибо починить критические баги было важнее. Тестирования из-за этого же тоже не получилось нормального провести, что так же отразилось на результате и игровом балансе. К тому же под конец я нехило так выгорел. Энивей очередная веха в моем инди пути, и я благодарен конкурсу, что оно все случилось. Надеюсь вам игра подарит положительных эмоций.
- 04 мая 2023, 06:46
- 015
27 комментариев