Как я пилю игру на Unity3D

Привет! Меня зовут Антон, это мой первый пост на DTF и я хочу рассказать о том, как я ушел (ухожу) из UX/UI в геймдизайн, для чего я разрабатываю ряд прототипов на Unity3D.

Я решил начать здесь блог после того, как прочитал этот пост про то, как Пётр делает свою игру на Godot. По-моему, очень круто!

Моя цель - профессионально заниматься геймдизайном, поэтому мой круг профессиональных интересов достаточно широк: это и разработка в том или ином виде (Unity, Blender, C#, Figma), и вещи непосредственно связанные с геймдизайном: баланс, кривая сложности, нарратив и так далее.

Он смог и я смогу
Он смог и я смогу

Проекты я делаю для мобильных устройств, создаются они для портфолио и вряд ли когда-нибудь будут монетизироваться.

Я принимаю любые бесплатные советы, мне точно есть чему учиться :)

Как это началось

Идеи заниматься геймдевом посещали меня уже довольно давно, и около 5-7 лет назад я впервые попробовал написать игру. Небольшой ресерч привел меня к Corona SDK (ныне Solar2D), в основе которого лежал физический движок Box2D. Корона обещала легкий вход благодаря языку Lua и довольно подробной документации. На тот момент мои навыки кодинга ограничивались турбо-паскалем и щепоткой Java. И тогда это выглядело классной идеей!

Фото coronalabs.com
Фото coronalabs.com

Месяц-другой и я сделал первые игры, и вау было уже в том, что они работали и крашились почти никогда. Проекты были загружены в Google Play и AppStore, однако особой популярности не снискали. Мой код работал, но при создании всех этих проектов были допущены фундаментальные ошибки:

  • Для этих игр не создавалось никакой документации, всё держалось в голове. Это были простые игры, но даже для них стоит писать доки хотя бы в приблизительном виде, и главное - продумывать всё заранее
  • Я никому их не показывал во время разработки. Тотальный факап, я мог бы гораздо быстрее понять, что делать ЭТО не надо вообще
  • Я работал один, хотя рисовать я не умею почти совсем. Это большая проблема, если ты делаешь игру в 2D, потому что моделинг оказался более технически понятным процессом
  • Прозвучит цинично, но не надо работать с непопулярными движками/технологиями. По факту они никому не нужны, если вы захотите устроиться в студию, ваш стек окажется никому не нужен
  • Самиздат - ну такое. Не скажу про всех, но это точно и не для всех 🙂
  • Эти игры были отстойными вследствие вышеперечисленного

Тогда я махнул на всё это рукой и продолжил работать в совершенно несвязанной сфере, и в итоге могу сказать: не стоит упираться и рассчитывать на самиздат. Я немного утрирую, но для нормальных людей это выглядит примерно как создание автомобиля с нуля у себя в гараже. Эта штука не поедет.

Какое-то время назад я выгорел на поприще дизайнера интерфейсов и хочу перемен и реализации в геймдеве.

Концепт

На сегодняшний день я не делаю “игру мечты”, очевидно, это провальная идея, если ты один и ты не гений (а я точно нет). Да, некоторые инди-проекты стали хитами, но они всё равно делались профессионалами, у которых есть опыт и практические навыки, и не в одиночку.

Я немного поковырял гиперказуальные игры, но решил что стоит обратить внимание на более сложные проекты, так как в ГК понятие геймдизайна своё, особенное.

Поэтому было принято решение брать популярные механики, но докручивать их до чего-то более сложного. И я постараюсь объяснить, для чего.

Выбран жанр приключений, в котором есть замкнутый, разделенный на несколько локаций мир – большой дом. Между локациями можно свободно перемещаться, и для выбора именно такой концепции есть рациональные причины:

  • Техническая: одна небольшая локация будет прилично работать даже на слабых смартфонах. Делать открытый мир с подгрузкой при перемещении значило бы дебажить сильно больше, а сроки у меня не резиновые. Делать линейное повествование я не стал, потому что…
  • Сделать много уникальных неповторяющихся уровней сложно с точки зрения трудозатрат на моделинг, левел-дизайн и такую рутину как запекание света и опять же отлов багов (например, трудно-проходимых мест из-за какого-нибудь коллайдера).
  • Каждый отдельный уровень я стараюсь делать так, чтобы он побуждал к разной манере игры: где-то очевидно применение стелса, где-то есть нечто похожее на платформинг, где-то будет тусить большой страшный босс, который навяжет сражение (это имеет отношение и к кривой сложности, об этом чуть ниже)
  • Маленький уровень загружается очень быстро
Этот уровень будет переделываться, потому что там негде прятаться. Это отстой
Этот уровень будет переделываться, потому что там негде прятаться. Это отстой

Кор-механики

  • Стелс
  • Поиск предметов
  • Сражение с помощью графических заклинаний

Здесь стоит оговориться, что игрок стартует без особых навыков, поэтому предполагается, что эти механики будут сменяться именно в таком порядке.

Отсюда вытекает подход к кривой сложности.

Первая локация после первого сейф-спейса насыщена укрытиями, она буквально кричит о том, что надо прятаться и пробираться сквозь нее дальше.

Много укрытий, мало охранников

Игрок пока не готов к конфронтации с врагами, но он может без особых проблем прятаться. Враги на уровне есть, они такие же агрессивные, как и всегда, но пока что столкновение с ними не только не обязательно, но и маловероятно. В случае же, если игрок будет игнорировать правила игры, он будет наказан лещем.

Далее игрок встречает первых npc, которые дают ему простейшее задание: найти и принести предмет, который лежит где-то здесь же рядом и взамен выдает часть заклинания. Таким образом, игрок продвигается по карте с ростом своих возможностей, нет искусственного барьера (“нет, мы не пустим тебя сюда, пока ты не соберешь N предметов”), в сложной локации он просто вступит в бой, проиграет его, узнает что-то об этой локации, новом противнике, и заспавнится в последнем сейвспейсе. Я считаю, это логично и очень погружает.

При этом в любой момент можно вернуться в “простые” локации, чтобы накопить маны.

Система врагов

Просто расставить ботов по картам очень заманчиво, но я решил, что это, во-первых, делает стелс слишком сложным на первых этапах, а во-вторых, делает мир слишком постоянным. Поэтому:

  • По уровню ходят охранники. У них есть точки интереса на карте, которые они последовательно проверяют (опять же их перемещение по карте более нарративно, чем ждущий враг). Сами по себе они не могут нападать на персонажа, но при его обнаружении поднимают уровень тревоги, и при ее высоком уровне натравливают на игрока ботов. Мне очень нравится уровень тревоги полиции в Mafia 2, где у тебя есть несколько секунд, чтобы скрыться из вида, пока тревогу не подняли. Я адаптировал этот концепт под себя: попасться одному охраннику один раз не страшно.
  • Есть три вида дефолтных врага, вид которых продиктован сеттингом, а характеристики - дизайном.
  • Манекен/скелет - ходит медленно, бьёт очень сильно и только если подойдет вплотную. Есть секунда, чтобы увернуться
  • Приведение - ходит чуть быстрее, бьёт средне, но делает это на небольшом расстоянии от врага без задержки
  • Демон - стреляет в игрока паверболами, телепортируется к нему, но в заранее обозначенное место.
  • Враги копятся на уровнях. Сами они никуда не уйдут
  • Разные враги убиваются разными заклинаниями

Точные значения еще предстоит достроить, но их уровень урона на единицу игрового времени должен быть примерно одинаковым.

Убить любого из них без заклинаний невозможно, но можно попробовать убежать, что на первых локациях ЗНАЧИТЕЛЬНО сложнее, чем прятаться от охранника

Цели игрока

Долгосрочная цель - выбраться из этого мира, спасти похищенных. Выход обозначается сразу в самом начале, но он заперт - надо получить все ключи.

Среднесрочная цель - продвижение по локациям, сохранение в более выгодных сейф-спейсах.

Краткосрочная - выполнение короткого квеста или его поиск.

Важной оговоркой является то, что с учетом мобильной платформы геймплей не является хоть сколько-нибудь хардкорным. У стелса ноги растут от пакмана: мы видим всех ближайших врагов и двигаемся по коридорам так, чтобы не встречаться с ними. Артефакты, нужные, чтобы копить ману, также разбросаны по уровню, их надо подбирать. В игре нет смерти ни нарративно, ни геймплейно – восстановление всегда происходит в последнем месте сохранения, почти не наказывая игрока за ошибку.

Заклинания представляют собой мини-игру, в которой нужно в правильной последовательности и вовремя соединить точки. Мне кажется это более интересным, чем просто накопленная возможность, потому что (извините за очередной список):

  • Открывает простор для исследования. Заклинание можно как узнать, так и подобрать
  • Не вырывает игрока из погружения, является частью мира, а не интерфейса
  • Является игрой само по себе

В итоге

А в итоге это как бы аркадное приключение, но с чуть более сложными механиками, которые, однако, не требуют (не должны требовать!) отдельного туториала.

Я уже пустил под нож отдельные механики типа квестов на время и стрельбы из огнестрельного оружия, потому что это либо не вписывается в сеттинг, либо убого играется с видом с потолка на сенсорном экране 🙂

Че там с Unity

Начну с того, что для игры написано определенное количество кода на C#, что оказалось не сложнее, чем писать на том же Lua. Он, наверное, не идеален, но работает как надо, спасибо всем чувакам с ютюба. При этом для расчета пути по локации для ботов у Unity есть своя прекрасная библиотека AI, которая решает огромную рутинную задачу вообще без моего участия.

Как я пилю игру на Unity3D

Большинство теней и освещения запекается, но в художественных целях используется и источник реального времени, который дает тень для не статичных объектов и корректно отрабатывает карты нормалей (для остальных тени просто отключаются).

Модели я делаю в Blender3D, они лоуполи, насколько это вообще возможно, для рельефа используются карты нормалей и карты высоты. Анимации используются от Mixamo: они может и не уникальные для моей игры, но точно лучше, чем сделаю я сам.

Я делюсь этим чтобы получить какой-то фидбэк, совет или кой-чего за воротник, тут уж как повезет. На всё ушло чуть меньше месяца, с учетом совмещения с другой периодической работе на фрилансе, и еще примерно столько же скорее всего я потрачу на завершение проекта.

5757
49 комментариев

Спасибо тебе Антон! Первая интересная статья за весь день. Какой же это кайф, прорываясь через тонны плача недовольных снежинок наконец то найти что то полезное на этом сайте.

4
Ответить

Комментарий недоступен

5
Ответить

Комментарий недоступен

2
Ответить

Комментарий недоступен

1
Ответить

Привет!
1. Нет, наследования пока нет, а интерфейсы свои
2. Опять же нет, но уже читаю доки, спасибо) Пока что всё сразу висит на объекте
3. Сохранения есть, сейчас они сделаны самым простым способом через PlayerPrefs, в другом проекте я использовал сохранение через их json
4. Когда как, на самом деле, удобно, когда объект сам находит нужные вещи, но часть вещей задаю через инспектор. Вроде бы и понятно, что чем меньше публичных переменных, тем лучше, но я точно сталкивался с проблемой, когда Find не успевал вовремя отработать.

На самом деле я бы не сказал, что я делаю это с какой-то особой любовью, скорее с большим интересом и желанием сделать хорошо. Ну и мысли мои обращены больше к геймплею, чем к техническим решениям, хотя собирать проект мне лично тоже очень интересно

2
Ответить

Успехов в разработке! Чёто ниодин видосик не грузится, у меня только так?

1
Ответить

Спасибо! Вообще вроде без проблем играется, может кеш почистить надо?)

Ответить