Создаём простую 3D-гонку на Unity
Гонки — один из самых популярных и простых в реализации игровых жанров. Рассказываем, как за один день создать простую 3D-гонку на Unity.
vlada_maestro / shutterstock
В этой статье мы создадим простую гонку на Unity, в которой будут:
- управление машиной;
- аварии;
- музыка и звуковые эффекты;
- бесконечная дорога;
- очки;
- меню.
Мы уже несколько раз писали, как реализовать такие вещи, поэтому в этой статье сосредоточимся на том, как использовать Unity для создания самой гонки, не вдаваясь в подробности работы с интерфейсом движка.
Если вы раньше не работали с Unity, рекомендуем ознакомиться с этими статьями:
- Как создать 2D-игру на Unity — введение в Unity.
- Что такое ассеты в Unity — добавление компонентов игры.
- Как создать 2D-шутер в Unity — работа с префабами.
- Меню для игры на Unity — об интерфейсе и работе с файлами.
Финальную версию проекта со всеми ассетами можно найти в этом репозитории на GitHub.
Подготовка к проекту
Для начала нужно создать 3D-проект в Unity и импортировать модели и звуки. Вы можете использовать свои или взять те, что находятся в репозитории.
Музыка и звуки найдены на бесплатных сайтах. Машины скачаны из Asset Store, а всё остальное я смоделировал самостоятельно (да, это всего лишь дорожный блок и монетка, но я старался).
Когда всё будет скачано и добавлено в проект, можно начинать.
Добавление дороги
Создайте пустой объект и назовите его Road — в нём будут размещаться все машины и дорожные блоки.
Добавьте в него первый блок:
У объекта Road координаты должны быть по нулям, а у блока X можно поставить на ноль либо на -24.69 — столько он занимает места. Эта цифра нам понадобится, чтобы добавлять новые блоки.
Теперь для блока нужно подключить коллайдеры Box Collider. Но добавлять их нужно не на сам блок, а на дорожное полотно (Plane) и бордюры (Plane_002).
Для полотна сразу установите тег Road (его нужно создать, нажав на Add Tag). Затем приступайте к бордюрам. Это один объект, поэтому нужно просто добавить два коллайдера:
Для бордюров установите тег Wall (его тоже нужно создать). Теги пригодятся для того, чтобы определять, с чем именно сталкивается машина игрока.
После того как будет добавлен игрок, можно будет приступить к генерации бесконечной дороги.
Добавление игрока
Внутри объекта Road нужно создать ещё один пустой объект и назвать его Player. Внутри него добавьте пустой объект Model и камеру. В Model нужно поместить модель машины, а затем установить камеру сзади модели.
Для объекта Player добавьте компонент Rigidbody и два коллайдера:
Один из коллайдеров нужно установить как триггер — с его помощью будут проверяться столкновения с разными объектами.
Теперь нужно заставить машину двигаться. Для этого создадим скрипт Moving и прикрепим его к объекту Player.
В первую очередь добавим переменные:
Теперь в Unity нужно заполнить все публичные переменные. Пустыми пока можно оставить Control и Broken Prefab, потому что они ещё не готовы.
Переменная Rb будет добавляться скриптом в методе Start():
Внутри этого скрипта он использоваться не будет, но нужен, чтобы генерировать дорогу.
Вернёмся к движению:
Можно запустить сцену и проверить, как движется машина. Камеру перед этим лучше сместить вбок, чтобы видеть, вращаются ли колёса.
Теперь нужно написать скрипт, который позволит управлять машиной. Назовём его Controls и добавим несколько переменных:
Само управление выглядит так:
Ссылку на скрипт нужно добавить в Moving:
Затем нужно добавить в метод Update() скрипта Moving следующий код:
Его надо вставить сразу после объявления переменных newSpeed и sideSpeed. Теперь машиной можно управлять:
Генерация бесконечной дороги
Чтобы машина не падала в пропасть, нужно добавить бесконечную генерацию дороги.
- Перед машиной будет добавляться столько дорожных блоков, сколько нужно, чтобы не было видно пропасти.
- Когда машина проезжает достаточное расстояние от определённого блока, он удаляется, чтобы освободить оперативную память.
Для этого создадим скрипт RoadBlock и прикрепим его к дорожному блоку. В нём будет всего два метода:
Сохраните блок как префаб. А инстанцироваться новые объекты будут в скрипте Road:
Те блоки, которые есть на сцене, нужно поместить в коллекцию Blocks. Также надо сразу заполнить остальные переменные.
Теперь можно проверить, как это выглядит:
Генерация машин
Чтобы генерировать машины, нужно сначала создать префаб. Для этого можно скопировать объект Player, удалив камеру и скрипт Controls. Также лучше использовать другую модель, чтобы игрок не путался.
Затем в скрипте Road после добавления нового дорожного блока нужно добавить вот такой код:
Перед этим не забудьте добавить префаб в переменную carPrefab.
Добавление монет
Чтобы игра стала интереснее, можно добавить монеты, при столкновении с которыми игрок будет получать очки.
Для этого поместите на сцену модель монеты, к ней подключите коллайдер с триггером (он обрабатываться не будет, но нужен для того, чтобы машины NPC проходили сквозь монету).
Потом создайте скрипт Coin с таким кодом:
В качестве префаба звука пока можно использовать пустой объект. А сам код генерации можно добавить туда же, где происходит инстанцирование остальных объектов.
Можно проверять:
Получение очков
Чтобы игрок мог получать очки, в скрипт Controls нужно добавить следующие переменные:
Добавление очков будет происходить в файле Moving в блоке работы со скриптом Controls:
Чтобы выводить, сколько очков набрал пользователь, нужно создать элемент Canvas и добавить в него текстовый блок:
Для него создайте скрипт Scores со следующим кодом:
Обратите внимание, что тут используется не стандартный текстовый элемент, а объект из библиотеки TextMeshPro.
Обработка столкновений
Теперь нужно добавить логику столкновений с другими объектами. Для начала создадим префаб сломанной машины:
Это та же модель, но здесь для каждого колеса добавлен коллайдер и Rigidbody. То есть при столкновении у машины будут отлетать колёса.
Затем в файл Moving нужно добавить следующий код:
Переход в меню можно пока закомментировать, потому что оно ещё не готово.
Вот что должно получиться:
Работа со звуком
Теперь можно добавить звуки:
- музыку;
- звук мотора;
- звук столкновения с машиной;
- звук столкновения с монетой.
Чтобы добавить музыку, к объекту Player подключите компонент Audio Source:
Укажите файл, громкость и поставьте галочку возле Loop, чтобы мелодия повторялась.
Затем добавим звук мотора. Для этого найдите звук, в котором есть монотонный рёв. Его высота будет меняться программным путём, когда игрок будет ускоряться или замедляться.
Добавить к модели машины Audio Source:
А затем в файле Moving добавьте такой код:
Звук столкновения нужно добавить в префаб сломанной машины, убрав зацикливание. А звук монеты — в пустой объект, который мы инстанцировали в скрипте монеты при столкновении.
Главное меню
Последний штрих — главное меню. Оно будет находиться в отдельной сцене. Создайте скрипт, который будет называться Menu:
Добавьте кнопки и укажите методы, которые будут вызываться при нажатии на них:
При нажатии на Play будет вызываться метод Play(), а при нажатии на Exit — Exit(). Можно добавить монетки и несколько дорожных блоков, чтобы меню выглядело красивее.
Итог
Получилась довольно простая игра. Для разработчика это интересный опыт, но игрокам она быстро наскучит. Чтобы этого не произошло, можно добавить несколько простых улучшений:
- накопление денег;
- покупку новых машин;
- более высокие скорость и манёвренность для более дорогих машин;
- смену полос для машин и так далее.
Если же вы хотите делать игры покруче, записывайтесь на наш курс «Профессия Разработчик игр на Unity». На нём вы научитесь работать с шейдерами, графикой высокого разрешения и разными механиками, а также многим другим.