Unity3D: Урок по созданию трехмерной игры-платформера: Первые шаги

Первые шаги


В любой игре-платформере есть свой главный герой, которым управляет игрок. У нас это будет Lerpz.


Анимация Lerpz’а

В этой главе мы рассмотрим:

  • Реализация игры от третьего лица и управление камерой
  • Управление и смешивание анимации
  • Использование системы частиц для создания двигателей у реактивного ранца
  • Добавление мягких теней игровому персонажу
  • Отслеживание состояний игрока
  • Управление здоровьем игрока, гибель и перерождение.

Перед тем, как начать, нам нужно знать, о чем вообще игра. Короче говоря, нам нужен…

Сюжет

Наш герой Lerpz , он — пришелец, путешествующий по Миру Роботов Версии 2. Этот мир заменил ему Мир Роботов Версии 1, который пострадал от довольно мощного сегментационного дефекта и внезапно врезался в свое солнце много лет назад.

К несчастью, Lerpz’а постигла неудача: его космический корабль был конфискован местной коррумпированной полицией. Посмотрев вверху и внизу, Lerpz обнаружил свой космический корабль, но как он сможет забрать его назад у противного вспыльчивого кузена мистера Бига — у мистера Ивэна Биггера?

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

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

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

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

Включаем в проект Lerpz’а

  • Откроем проект и выберем Scenes -> TheGameScene.

Наш первый шаг — это добавить Lerpz’а в сцену:

  • Откройте папку Objects в окне «Project»;
  • Перетащите префаб Lerpz’а либо в окно «Scene», либо в окно «Hierarchy»;
  • Нажмите кнопкой мыши на модель Lerpz’a в окне «Hierarchy» и переименуйте его на Player;
  • Выделите объект Player , переместите курсор мыши в панель сцены и нажмите клавишу «F» (focus), чтобы перемесить центр сцены к модели Lerpz’а.
  • Передвиньте Lerpz’а на подиум с прыгающей панелью (ниша с желтыми шевронами), около тюрьмы. (Смотрите скриншот на следующей странице.)

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

  • Нажмите снова на кнопку Play , чтобы остановить игру.

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

alt
Позиционирование Lerpz’а в сцене

Камеры от третьего лица

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

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

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

  • Что должно происходить, если Lerpz находится за сплошной стеной? Должна ли камера переместиться выше и смотреть сверху вниз на игрока? Или она должна передвигаться в сторону?
  • Что если вражеский персонаж появляется между камерой и нашим главным героем?
  • Каким образом игрок будет контролировать работу камеры. Будут ли они родственны по отношению к ее точке обзора. Если так, то может получиться довольно запутанно в случае, если камера будет двигаться в неожиданном направлении во избежание препятствий.

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

Проект, поставляемый вместе с этим уроком, включает в себя несколько различных скриптов для камеры, но для целей данного урока, мы будем использовать скрипт SpringFollowCamera. Вы найдете его в окне проекта, внутри подпапки Camera, которая находится в папке Scripts.

  • Перетащите скрипт SpringFollowCamera из окна «Project» на объект NearCamera , который находится в окне «Hierarchy».
  • Нажмите кнопку Play.

Вы получите сообщение об ошибке. Оно возникает прямо справой стороны кнопок Play, Pause, Step в нижней части окна Unity.

  • Вызовите консоль отладки (Shift+Cmd+C / Shift+Ctrl+C на PC), если она еще не видна.

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

alt
Соообщение об ошибке «No target» («цель не определена»).
Подсказка Всякий раз, когда это возможно, окно отладки с журналом сообщений об ошибках будет показывать строчку, связанную с соответствующим игровом объектом (GameObject) в окне «Hierarchy», (или в окне «Project», если ошибка возникла в Префабе или в скрипте). Вы можете посмотреть на эту строчку на скриншоте выше.

Тип ошибки UnassignedReferenceException — один из тех, с которым вы вероятно будете встречаться очень часто, если вы — новичок в Unity. Это звучит ужасно, но все это означает только одно — то, что переменная скрипта не была определена. Журнал сообщений объясняет то же самое, поэтому давайте сделаем, как он предлагает:

  • Нажмите на объект NearCamera в окне «Hierarchy» и взгляните на свойства компонента (скрипта) SpringFollowCamera.

Свойство Target имеет значение None (Transform), оно определяет целевой объект, на который указывает камера. Давайте назначим его:

  • Остановите игру, если вы еще не сделали этого.
  • Если уже ничего не выбрано, то нажмите левой кнопкой мыши на объект NearCamera в окне «Hierarchy».
  • Перетащите объект Player из окна «Hierarchy» на установку Target , чтобы назначить его.

Делая изменения во время работающей игры

В процессе игры Unity позволяет вам изменять свойства различных игровых объектов и компонентов. Тем не менее, они не сохраняются! На тот момент, когда вы останавливаете игру, любые изменения обнуляются!

Если вы хотите, чтобы ваши изменения остались, то всегда сначала останавливайте игру!

Если вы нажмете теперь на Play , то камера все еще не будет работать. Вы увидите ошибки, связанные со скриптом SpringFollowCamera. Необходимо, чтобы к настройке target был присоединен скрипт ThirdPersonController, потому что камера от третьего лица тесно связана с управлением игрока: камера должна знать, что игрок что-то делает для того, чтобы суметь среагировать соответствующим образом.

Завершающие настройки должны выглядеть, как показано на изображении ниже:

alt
Установки скрипта ScriptFollowCamera.

Экспериментируйте со значениями, если вам не нравится то, как работает камера; это субъективная оценка и нет никакого конкретного решения по настройке в этом случае.

Это первая из зависимостей, в которой мы должны разобраться.

  • Завершите соединение между камерой и игроком, перетащив скрипт ThirdPersonController из папки Scripts->Player в окне «Project» на игровой объект Player (в окне «Hierarchy»). (Это действие разорвет связь с префабом.)

Скрипт ThirdPersonController также имеет свои собственные требования и зависимости. Самое важное из них — это компонент Character Controller. К счастью, скрипт уже сообщает Unity об этом, поэтому Unity добавит данный компонент для нас.

Взаимосвязи и зависимости

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

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

Определение всех таких зависимостей является ключевым элементом игровой разработки.

Теперь нам нужно добавить тег (tag) к игровому объекту Player. Для того, чтобы скрипты смогли отыскать игровой объект Player в сцене просто поручив Unity найти его с указанным тегом.

  • В объекте Player , который отображен в инспекторе, откройте выпадающее меню Tag и выберите тег «Player» , как показано на рисунке ниже.
alt
Выбор тега для игрового объекта Player.
Примечание Теги, указанные в меню, которое показано выше, предоставляются игровой средой Unity по умолчанию. Позже мы изучим, каким образом можно создать свои собственные теги (Tags) и слои (Layers).
  • Выберите объект Player и взгляните на окно «Inspector», которое должно выглядеть следующим образом:
alt
Компонент Character Controller и компонент-скрипт Third Person Controller на своих местах.

Наш следующий шаг — отрегулировать Character Controller. Сейчас, тот Capsule Collider (коллайдер), который он использует, расположен слишком низко по оси Y, поэтому Lerpz стоит в воздухе. (Вы можете заметить расположение коллайдера в окне сцены: это вытянутый голубой цилиндр каркасной формы.) Мы должны изменить значение параметра Center Y.

alt
Регулировка капсулы-коллайдера для объекта Character Controller, показанного в виде голубого каркаса.
  • Расположите Capsule Collider (коллайдер-капсулу) как показано на скриншоте выше. (Под небольшим экспериментированием подразумевается настройка Center для Character Controller по оси Y на 1.03, которая выровняет его нижнюю часть идеально со ступнями Lerpz’а)

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

Компонент Character Controller и скрипт Third Person Controller

Во многих играх, главный герой обладает невероятными физическими способностями, такими как: мгновенные поворот и торможение во время прыжка на неправдоподобные расстояния и другими действиями, которые сложно было бы смоделировать, используя традиционную физику. Поэтому Character Controller отделяет игровой персонаж от физического движка, предоставляя основные элементы управления для движения.

Character Controller упрощает движение игрока (и других персонажей), который содержит коллайдер-капсулу, привязанную к базовой системе движения, позволяющей персонажу передвигаться, взбираться шагами и скользить с уклонов. Вы можете изменить максимальный шаг и размеры скольжения в окне «Inspector».

Обычно Character Controller используется со скриптом, который «общается» с Character Controller и расширяет его возможности для удовлетворения потребностей игры. В нашем проекте скрипт Third Person Controller выполняет такую функцию и добавляет необходимую поддержку для игры-платформера. Также отслеживает джойстик, клавиатуру, мышь и другие устройства ввода, воздействует на них для того, чтобы управлять персонажем игрока.

Input Manager (Менеджер устройств ввода) Unity (Edit->Projets->Input Manager) позволяет вам определять, каким образом устройства ввода будут управлять игроком.

Примечание Нет ничего особенного в скриптах, которые мы используем для игрока. Это вполне обыкновенные скрипты Unity, которые были созданы для данного проекта. Не существует никакого скрипта Character Controller «по умолчанию».

Скрипт Third Person Controller уже является частью префаба, поэтому нет необходимости добавлять его.

Следующий шаг — сделать анимацию Lerpz’а правильно и добавить дополнительные движения, такие как: прыжок и удар кулаком…

Анимация Lerpz’а

С этого момента, Lerpz просто скользит вдоль декораций. Все потому, что Character Controller не управляет анимацией. Он ничего не знает о модели игрока, или какая последовательность анимации выполняется при каждом движении. Мы должны подключить Lerpz’а к его кадрами анимации и сделать это с помощью скрипта ThirdPersonPlayerAnimation.

  • Используйте меню Component, чтобы добавить скрипт ThirdPersonPlayerAnimation к игровому объекту Player.
alt
Добавление скрипта ThirdPersonPlayerAnimation к игровому объекту Player при помощи меню Component.

Если вы сейчас нажмете на Play, то Lerpz будет анимироваться правильно.

И так, что тут происходит? Что делает этот скрипт? Ответ заключается в том, как Unity управляет данными анимации персонажа.

Анимация персонажа

Кадры анимации персонажа создаются в программе трехмерного моделирования, например в 3DStudioMax, Maya, Blender или Cheetah3D. При импорте в Unity, данные кадры автоматически извлекаются и сохраняются в компоненте Animation.

Эти анимационные кадры назначены виртуальному скелету, который обычно используется для анимации базовой модели. Такие скелеты определяют каким образом сетка модели (mesh) — важные данные, определяющие видимые поверхности самой модели — изменяется и трансформируется движком, чтобы создать требуемую анимацию.

Скелеты и каркасы

Если вы знакомы с техникой кукольной (stop-motion) или пластилиновой («claymation») анимации, то вы наверняка в курсе о том, что там используются металлические каркасы. Анимированные модели построены вокруг этих каркасов. Виртуальные скелеты, используемые в трехмерных моделях, полностью эквивалентны им и не всегда так же сложны, как настоящие скелеты.

Компонент сетки (mesh) подобных моделей в большинстве случаев называется покрытой сеткой (skinned mesh). Виртуальный скелет снабжен костями под сеткой и определяет, каким образом происходит анимация сетки.

Смешивание анимации

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

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

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

Скрипт Third Person Player Animation

Модель Lerpz’а , которую мы используем, была создана для различных проектов и содержит пятнадцать анимационных кадров. Только одиннадцать используются в этом уроке. Если вы выберите объект Player в окне «Hierarchy» и взгляните на окно «Inspector», то вы увидите все пятнадцать кадров анимации, расположенных внутри компонента Animation, в котором только следующие фактически используются в данном уроке:

  • Ходьба — обычный цикл ходьбы.
  • Бег — анимация бега. (Зажмите кнопку Shift во время игры, чтобы бежать).
  • Удар кулаком — проигрывается, когда игрок атакует вражеских роботов-стражников.
  • Прыжок — проигрывается, когда Lerpz подскакивает в воздух.
  • Падение после прыжка — проигрывается, когда прыжок Lerpz’а достигает своего предела и он начинает падать.
  • Ожидание — цикл, проигрываемый, когда Lerpz находится в состоянии ожидания.
  • Прыжок со стены — анимация кувырка, проигрываемая, когда Lerpz спрыгивает со стены.
  • Реактивный прыжок — проигрывается, когда реактивный ранец Lerpz’а замедляет его падение.
  • Падения с края — проигрывается, когда Lerpz сходит с края платформы.
  • Шлепок — проигрывается, когда Lerpz был ударен роботом-стражником.
  • Приземление после прыжка — проигрывается, когда Lerpz приземляется после прыжка или падения.

Модель и анимация для Larpz’а были созданы при помощи Maya и импортированы в Unity. Для получения дополнительной информации относительно импортирования моделей и анимации, пожалуйста, смотрите Руководство Unity.

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

Движения Lerpz’а при атаке — его удар рукой — сделаны отдельно в скрипте ThirdPersonCharacterAttack. (Мы добавим этот скрипт позже.) Это может казаться условным разделением, но это не так: большинство основных движений — ходьба, бег, прыжки и т.д. — очень похожи в не зависимости от того, как выглядит персонаж игрока. Тем не менее, движения атаки и защиты, как правило, намного различны. В некоторых играх-платформерах у персонажа игрока может быть пушка; в других — он может выполнять движение боевого приема.

В данном уроке, Lerpz — мастер популярного Западного искусства рукопашного боя, известного как Fisticuffs (Кулачный бой), название, которое переводится как «ударение своего оппонента очень сильно кулаком». Анимация — простой удар кулаком.

Гизмо (Gizmos)

ThirdPersonCharacterAttack также включает в себя полезную особенность для тестирования: гизмо, которое отображает сферу, показывающую область, в пределах которой действует удар кулаком Lerpz’а. Гизмо рисуется внутри одной из двух управляющих функций. В этом примере, гизмо — каркас желтой сферы, изображенный в позиции удара кулаком и указывающий его область воздействия — отображенное в ответ на функцию OnDrawGizmosSelected(). Эта функция должна быть статичной и вызываться сама редактором Unity. Альтернативой является функция OnDrawGizmos(), которая вызывается редактором Unity с каждым циклом обновления, в не зависимости от того, был ли выбран родительский GameObject (игровой объект).

Реактивный ранец

alt
Реактивный ранец Lerpz’а в действии.

С этого момента наш персонаж бегает и прыгает, но его реактивный ранец пока еще не работает. Lerpz использует реактивный ранец, чтобы снизить скорость падения. Движение уже готово, но струя реактивного ранца не анимирована вообще. Чтобы заставить струю работать, мы должны будем добавить Particle Systems (системы частиц) и компонент Point Light (точечный источник света). Системы частиц будут выдавать эффект, подобный пламени, в то время как точечный свет будет создавать иллюзию огня, действующую в виде источника освещения.

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

Что такое система частиц?

Системы частиц испускают десятки частиц — обычно плоские двумерные квадраты или спрайты — в трехмерное пространство. Каждая частица испускается с установленной скоростью и темпом ускорения, и временем жизни на определенное время. В зависимости от настроек и используемых материалов, системы частиц могут использоваться для имитации огня, дыма и взрывов на звездных полях.

Добавление системы частиц

  • Используйте меню GameObject чтобы создать пустой игровой объект в окне «Hierarchy».
  • Переименуйте игровой объект в «Jet».

Выберите этот новый игровой объект и добавьте к нему:

  • Компонент Ellipsoid Particle Emitter
  • Компонент Particle Animator
  • Компонент World Particle Collider
  • Компонент Particle Renderer
  • Уберите метку «Enabled» в окне «Inspector» компонента Particle Renderer, чтобы временно отключить его.
  • Разместите объект «Jet» сразу под выхлопную трубу со стороны правой руки Lerpz’а
  • Установите метку «Enable» для компонента Particle Renderer.
  • Отрегулируйте настройки для компонента Ellipsoid Particle Emitter, как показано ниже:
alt
Установки компонента Ellipsoid Particle Emitter.
Подсказка Если частицы не движутся прямо вниз, используйте инструменты вращения, чтобы перевернуть объект, пока струя не будет двигаться в соответствии с выхлопами.
Когда все будет сделано, система частиц будет присоединена к «туловищу» дочернего объекта Player в окне «Hierarchy». Это заставит струю следовать за движениями игрока. Тем не менее, на данный момент мы в первую очередь заинтересованы в том, чтобы она была видна справа, поэтому особо не беспокойтесь о точном размещении.

Установки Min Size и Max Size определяют размер диапазона частиц. Установки Min Energy и Max Energy определяют минимальное и максимальное время жизни частиц. Частицы будут иметь короткую продолжительность существования — 0.2 секунды в данном случае — перед исчезновением.

Мы устанавливаем количество частиц для испускания 50. Диапазон Min Emission и Max Emission определяет, сколько частиц мы хотим видеть на экране одновременно, и насколько изменчивым должно быть выделение частиц. Мы решили установить для минимального и максимального диапазон близкие величины, иначе будет похоже, что реактивный двигатель «чихает», а не работает ровно. В результате должен быть плавный поток частиц.

Примечание Мы отключили настройку «Simulate in Worldspace» (имитация в трехмерном пространстве). Это поможет создать впечатление горячей быстрой струи газа, а не слишком медленного пламени, даже если частицы будут двигаться достаточно быстро. Заставив струю игнорировать повороты и вращения, мы сделали ее похожей на горячее устойчивое пламя.
  • Теперь установим настройки для компонента Particle Animator, как показано ниже:
alt
Установки компонента Particle Animator. Значения в таблице определяют записи Color Animation. Не забывайте также регулировать другие настройки!

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

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

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

Далее компонент Particle Renderer. Этот компонент рисует каждую частицу, поэтому ему нужно сообщать как будут выглядеть частицы. Он также определяет материал, который используется для визуализации каждой частицы. Мы хотим эффект в виде струи пламени, поэтому будем использовать материал «fire add», который можно найти в: Particles->Sources->Materials->fire add.

Подсказка Этот игровой ресурс также содержится в папке Standard Assets.
  • Установите значения компонента, как показано ниже:
alt
Настройка компонента Particle Renderer.

Установка Stretch Particles сообщает Unity отображать ли частицы растянутыми, если они будут двигаться с высокой скоростью. Мы хотим, чтобы частицы растягивались немного в зависимости от их ускорения. Это добавит слегка уловимый намек и заставит маленькие круглые формы, которые мы используем для струи, смешиваться больше друг с другом.

Примечание Настройки Cast Shadows и Receive Shadows не возымеют действия, если вы не используете пользовательский шейдер. Это довольно обширная тема, выходящая за рамки данного урока.

Добавление света

Струя выглядит холодной, но на самом деле это иллюзия: система частиц просто разделяет множество крошечных изображений, но в результате эффект пламени не испускает света. Чтобы доделать иллюзию, мы создадим отдельный игровой объект Point Light (точечный источник света). Мы будем его включать и выключать в одно время с реактивными двигателями. В результате получится струя пламени, которая будет подсвечивать ближайшее окружение. (Мы будем использовать только единственный источник света, а не по одному на каждую струю; это сэкономит вычислительные мощности во время работы иллюзии.)

  • Создайте новый игровой объект Point Light.
  • Назовите его «Jet Light» и разместите между двумя смоделированными реактивными двигателями на ранце Leprz’а. (Мы вскоре вернемся к системе частиц для реактивных двигателей). Этот источник света будет создавать иллюзию того, что из струя двигателей испускает свет.

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

  • Выберите источник света и отрегулируйте настройки, как показано ниже:
alt
Настройки источника освещения для реактивного ранца.

Почему нет никаких теней?

Тени в вычислительном отношении достаточно затратны для большинства аппаратных устройств. Поэтому имеет смысл избегать вычисления с ними, если это возможно, и это именно та ситуация, где вы можете «схалтурить». Реактивные двигатели не слишком большие, поэтому они должны подсвечивать только спину Lerpz’а. Точечный источник света также должен отражаться от окружающих предметов, но не должен быть слишком ярким, делая заметным отсутствие теней.

Следующий шаг — обновить игровой объект Player для того, чтобы включить в него объекты jet и light (источник света). Чтобы сделать это, для начала добавим объект Jet в окно «Project» в качестве префаба:

  • В окне «Project» выберите (пустую) папку Player, затем нажмите Create…
  • Из раскрывающегося меню выберите Prefab. Будет создан пустой объект префаба.
  • Переименуйте пустой префаб в «Jet».
  • Перетащите новый блестящий объект Jet из окна «Hierarchy» на новый префаб.

Имя Jet в окне «Hierarchy» должно стать синим и тем самым показать, что объект связан с префабом. Мы будем использовать два экземпляра префаба Jet для реактивного ранца Lerpz’а. Использование префаба означает, что мы можем более точно настроить оба двигателя простым редактированием оригинального префаба.

  • Удалите оригинальный объект Jet из окна «Hierarchy». (Однако оставьте источник Jet Light там, где он находится!)

Теперь мы добавим объекты jet (дважды) и light (один раз) к объекту Player:

  • Выберите объект Player в окне «Hierarchy».
  • Открывайте его пока не найдете дочерний объект torso.
  • Перетащите объект префаба Jet на этот объект дважды. Это создаст два экземпляра Jet.
  • Переименуйте оба экземпляра Jet в Jet L и Jet R,
  • Перетащите объект Jet Light на такой же объект torso.

Теперь у вас будет иерархия объектов, которая будет выглядить следующим образом:

alt
Иерархия реактивного ранца.
  • Используйте инструменты манипуляции Unity для размещения каждого префаба Jet под каждым выхлопным выходом реактивного двигателя Lerpz’а. Вам, скорее всего, нужно будет вращать их, чтобы частицы двигались в правильном направлении.
  • Передвиньте объект Jet Light в позицию между двумя префабами Jet.

Когда вы достигните желаемого, у Lerpz’а должны будут появиться две огненные струи, неудержимо вырывающиеся из реактивного ранца во время его вращения. Мы почти закончили!

Последний шаг — заставить префабы Jet и объекты Jet Light активироваться только при прыжке персонажа. Это достигается посредством скрипта.

  • Взгляните на скрипт JetPackParticleController в папке Scripts -> Player и перетащите его на объект «Player», находящемся в самом верху окна «Hierarchy». Таким образом будет добавлен скрипт для персонажа игрока.

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

alt
Реактивный ранец Lerpz’а в действии.

Размытые тени

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

Одни из таких самых важных элементов — система теней и освещения. Чтобы улучшить производительность световые эффекты часто предварительно визуализируются в текстурах художником при помощи программы трехмерного моделирования — техника известная как «запекание». Данная техника работает хорошо только на статичных объектах, таких как наборы и фиксированные опоры. (Мы намеренно избегали этой техники для игровых ресурсов данного урока.) Персонаж, прогуливающийся под уличным фонарем, должен реагировать на такой свет в реальном времени. Дорога под персонажем может иметь «запеченный» свет, но персонаж не может использовать такую хитрость и также должен реагировать на источники освещения.

Решение состоит в том, чтобы позиционировать динамические источники освещения там, где они нужны — если вы используете «запеченные» текстуры, не забывайте добавлять свет везде, где предполагается запеченное освещение — однако заставляйте источники освещения воздействовать только на движущиеся объекты. Источники света уже расположены в сцене для вас.

Теперь остается последний элемент: тени.

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

Тени могут быть созданы при помощи источников освещения, с тенью, просчитанной и визуализированной в реальном времени графическим движком. Тем не менее, такие тени затратны с точки зрения вычислительной мощности. Кроме того, не все графические карты умеют быстро и эффективно высчитывать тени; старые карты не могут сделать этого вообще.

По этой причине мы будем использовать размытую тень для Lerpz’а.

Добавляем размытую тень (Blob Shadow)

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

В Unity имеется префаб Blob-Shadow в коллекции Standard Assets (стандартные ресурсы), поэтому мы будем использовать его, а не создавать все сами. Данный ресурс уже импортирован и добавлен в проект и находится в папке Blob-Shadow. Откройте эту папку, нажмите кнопкой мыши на префаб blob shadow projector и перетащите его на объект персонажа Player, находящийся вверху, в окне «Hierarchy». После чего Projector будет добавлен чуть ниже верхнего уровня в иерархии объекта Player:

alt
Префаб Blob Shadow Projector в иерархии объекта Player.

Далее, вам нужно будет изменить параметры расположения и поворота объекта blob shadow projector так, чтобы он находился прямо над персонажем и указывал прямо вниз на поверхность пола.

  • Выберите раскладку просмотра 4-Split.
  • Установите значение Rotation для объекта blob shadow projector на 90, 180 и 0 соответственно.
  • Теперь используйте проекции обзора side и top для того, чтобы поместить projector над головой Lerpz’а. Возможно, вам нужно будет немного подогнать его для того, чтобы получить тень желаемого размера.

Создание нового слоя (Layer)

С этого момента вы заметите, что пятно также проецируется на Lerpz’а. Но мы не хотим, чтобы это происходило. Существует два варианта, чтобы обойти это: передвиньте настройку Near Clip Plane дальше от проектора или просто укажите ей не осуществлять проецирование на объекты в определенных слоях. Мы будем использовать второй вариант.

Почему бы не отрегулировать Near Clip Plane?

Данная техника может показаться намного проще с первого взгляда, но поверхность должна быть отрегулирована скриптом с тем, чтобы принять во внимание анимацию Lerpz’а. Его ноги двигаются дальше, когда он прыгает, после чего приближаются к нему немного ближе, когда он приземляется снова. Поскольку тень должна быть постоянно спроецирована на поверхности пола, где стоит Lerpz, это значит, что Near Clip Plane не может оставаться одной и той же в течение всех анимационных кадров.

  • Откройте игровой объект Player.
  • Откройте в раскрывающемся меню окна «Inspector» элемент Layer.
  • Выберите Add new layer…
  • Нажмите правой кнопкой мыши на первом пустом элементе User Layer и назовите его noShadow.
alt
Добавление нового слоя при помощи Tag Manager.
  • Теперь нажмите снова на объект Player в окне «Hierarchy» , чтобы вызвать обычные настройки инспектора.
  • Нажмите на раскрывающееся меню «Layer» и установите слою новое имя noShadow. Unity спросить желаете ли вы выполнить команду для всех детей игрового объекта: нажмите на «Change Children Layers».

Далее нам нужно указать объекту Blob Shadow Projector , чтобы он не проецировал на объекты, находящиеся в данном слое.

  • Движемся на в свойства blob shadow в инспекторе и смотрим на элемент Ignore Layers, который находится в компоненте Projector.
  • Используем раскрывающееся меню справа, чтобы выбрать слой noShadow (который также должен будет примениться к детям), как показано на изображении:
alt
Настройки компонента Blob Shadow Projector.

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

Нам нужно, чтобы собираемые предметы выделялись в любое время, поэтому имеет смысл указать объекту Blob Shadow Projector не затрагивать их также.

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

  • Сначала остановите игру.
  • Теперь перейдите к окну «Project» и разместите объекты FuelCellPrefab и HealthLifePickUpPrefab. Вы найдете их в папке Props.
  • Выберите корневой объект каждого префаба и установите его слой (Layer) на noShadow, как показано ниже:
alt
Установка значения слоя изменена на «noShadow».
Примечание Изменяя родительский объект, Unity часто спрашивает, применить ли изменения также к детям объекта. Подобные действия могут быть опасны, если вы не продумали все последствия.
В этом случае, нужно, чтобы все дочерние объекты игровых объектов «FuelCellPrefab» и «HealthLifePickUpPrefab» находились в таком же слое «noShadow», поэтому, когда Unity спросит, согласитесь распространить изменения.

Концепции программирования с помощью скриптов

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

Основной принцип остается неизменным на протяжении многих лет. Компьютеры всего лишь изменили физический механизм, построенный из стали и пружин, в виртуальный механизм, управляемый по спискам инструкций. Unity обращается к таким спискам инструкций посредствам скриптов.

Большинство скриптов сосредоточены на понятии, популярном в игровой индустрии: конечный автомат. Конечный автомат, в сущности, определяет систему взаимодействующих условий, известных как состояния.

Состояние может быть практически чем угодно, например, должен ли объект быть визуализирован вообще, или должен ли он соответствовать законам физики, быть подсвеченным и отбрасывать тени, должен ли он отскакивать от поверхности, каково его расположение на экране, и так далее. Окно «Inspector» позволяет изменять множество подобных состояний напрямую, потому что они являются общими почти для всех игр.

Тем не менее, существует еще один тип состояний, которой является специфическим для игры сам по себе. Unity не знает, что персонаж игрока — это пришелец, сколько повреждений Lerpz может выдержать или то, что у Lerpz’а есть реактивный ранец. Каким образом Unity может определить, какое поведение требуется для роботов-стражников и как они должны взаимодействовать с Lerpz’ом?

Это именно то место, где в действие вступают скрипты. Мы используем скрипты, чтобы добавить интерактивность и специфику управления состояниями в игре.

Наша игра должна будет отслеживать некоторое количество состояний, которые перечислены ниже:

  • Здоровье игрока;
  • Количество канистр с горючим, которые собрал игрок;
  • Собрал ли игрок достаточно горючего, чтобы разблокировать силовое поле;
  • Вошел ли игрок на прыгающую платформу;
  • Коснулся ли игрок собираемого предмета;
  • Коснулся ли игрок космического корабля;
  • Коснулся ли игрок точки перерождения;
  • Должен ли отобразиться экран Game Over или Game Start;
  • …и другое.

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

Организация и структура

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

Имеется группа методов, с помощью которых мы можем устанавливать такие связи:

  • Добавление связи, расположенной в окне «Inspector» , на которую вы устанавливаете соответствующий объект. Такой подход идеален для скриптов общего назначения, которые вы намереваетесь повторно использовать в других проектах.

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

    Мы используем этот вариант для камер в сценах-заставках в параметре LevelStatus. (Этот скрипт в данный момент всего лишь короткий отрывок, уже прикрепленный к игровому объекту Level). Он дает нам гибкость при установке нескольких камер: одна для заставки «level exit unlocked» и другая для сцены «level complete». На практике мы используем только две камеры в игре: одна для игрока и сцены «level complete», другая для заставки «unlocked». Но данный вариант изменяет это.
  • Установка связи в пределах функции Awake() скрипта. Функция Awake() вызывается для каждого скрипта, который вы написали перед тем, как произошел первый вызов события Update() для игрового объекта, к которому она присоединена. Установка связи в этом месте позволяет вам кэшировать результат для дальнейшего использования в функции Update(). Обычно вам следовало бы установить личную переменную со связью на другой игровой объект или компонент, к которому вам нужно получить доступ в скрипте. Если вам необходимо сделать вызов команды GameObject.Find() для того, чтобы определить местоположение определенного объекта, то намного лучше сделать это только один раз внутри функции Awake() , поскольку команда GameObject.Find довольно медленная.

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

    Например, скрипт LevelStatus, который управляет состоянием уровня, кэширует ссылки на группу других объектов, включая объект Player. Мы знаем, что они не будут изменяться, поэтому мы также можем заставить компьютер делать эту работу за нас.
  • Установка связи во время работы функции Update(). Эта функция вызывается хотя бы раз за игровой цикл, поэтому лучше избегать использования вызовов медленных функций здесь. Тем не менее, функции GameObject.Find() и GetComponent() могут быть достаточно медленными.

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

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

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

Скрипты в визуальной среде разработки

Unity — необычный инструмент в том, что он сфокусирован на визуальных ресурсах, а не на связях и соединениях между ними. Большой проект на Unity может иметь десятки скриптов различной сложности, разбросанных по всей иерархии, поэтому проектирование, применяемое для этого урока, использует некоторые объектно-ориентированные технологии с тем, чтобы облегчить разработку.

Скрипт, который имеет дело с конкретной частью механизма состояний — например, анимация игрока — также должен отслеживать соответствующие переменные состояний. Это может сделать некоторые вещи немного сложнее, когда скрипту нужен доступ к переменной состояния, хранящейся в другом скрипте, вот почему некоторые скрипты кэшируют значения локально, чтобы сделать доступ к информации более быстрым. Данная техника также время от времени приводит к цепочкам команд, где функция в одном скрипте только вызывает схожую функцию в другом скрипте. Процесс управления гибелью и перерождением игрока является одним из примеров.

Примечание По мере увеличения своего опыта, работая в среде разработки Unity , вы будете находить другие способы управления состояниями, которые, возможно, будут намного приемлемы для ваших собственных игр. Шаблон проектирования, применяемый в данном уроке, не должен рассматриваться как решение «одно для всех»!

Если хотите, то вы можете превратить игровой объект Player в префаб, который будет содержать все ваши изменения, таким образом, вы сможете повторно использовать его в других проектах в качестве начальной отправной точки:

  • Нажмите левой кнопкой мыши на папке Player в окне «Project».
  • Создайте новый префаб. (Он появится в папке Player.)
  • Дайте новому префабу соответствующее имя — Я предлагаю LerpzPrefab.
  • Перетащите игровой объект Player на LerpzPrefab , чтобы завершить данный процесс.

Гибель и перерождение

Персонажи игры-платформера имеют склонность рисковать своими жизнями и Lerpz — не исключение. Мы должны быть уверены в том, что он теряет жизнь, если выпадает из уровня. Мы также должны заставить его появиться снова в безопасном месте на уровне — часто называемой «точкой перерождения» — чтобы он смог продолжить свое поиски.

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

Лучшее решение — использовать квадратный коллайдер, чтобы отслеживать любое выпадение с уровня. Мы сделаем его очень длинным и широким, так что, если игрок попытается использовать реактивный ранец во время прыжка, мы все еще сможем поймать его. Тем не менее, Lerpz’у нужно будет где-то перерождаться. Мы дойдем до точек перерождения чуть позже. Сначала, давайте создадим квадратный коллайдер:

  • Создайте пустой игровой объект.
  • Переименуйте новый объект в FalloutCharacter.
  • Добавьте к нему объект Box Collider.
  • Добавьте скрипт Fallout Death из Component -> Third Person Props.

Используйте окно «Inspector» , чтобы установить значения, как показано на скриншоте ниже:

alt
Настройки компонента Fallout Catcher.

Скрипт Fallout Death

Этот скрипт небольшой, потому что он просто делегирует всю работу скрипту ThirdPersonStatus. (Он должен быть присоединен к Lerpz’у , но мы пока что не будем этого делать.)

Код для управления триггером коллайдера находится в OnTriggerEnter(). Эта функция вызывается Unity когда Box Collider сталкивается с другим игровым объектом, в котором содержится компонент Collider, например, такой как Lerpz или вражеский персонаж.

Имеется три вида проверки: одна для игрока, одна для простого объекта RigidBody и третья проверяет, есть ли у объекта компонент CharacterController. Вторая проверка ищет любые опоры, такие как ящики или коробки, выпадающие с уровня. (У нас нет таких предметов в этом уровне, но вы можете добавить их, если хотите поэкспериментировать.) Третья проверка используется для того, чтобы определить вражеских персонажей, поскольку они не имеют обычной присоединенной физики.

Если игрок сталкивается с квадратным коллайдером, то код просто вызывает функцию FalloutDeath() в скрипте ThirdPersonStatus , который находится у Lerpz’а.

Если другой объект с объектом-коллайдером сталкивается с нашим игровым объектом, то мы просто уничтожаем его, убирая его со Сцены, иначе он будет падать бесконечно.

Кроме того, у нас есть:

  • Полезная функция — Reset() — которая подстраховывает любые необходимые компоненты, которые также присутствуют. Эта функция вызывается Unity автоматически при добавлении компонента в первый раз. Ее также можно вызвать из редактора, нажав на значок шестеренки, находящийся справа от имени любого компонента в окне «Inspector»:
alt
Команда Reset в сплывающем меню.
  • Директива @Script, которая также добавляет скрипт прямо в меню компонентов Unity. Это удобно и избавляет от поисков компонента в окне «Project» — полезно, если у вас сложный проект с большим количеством ресурсов.
    Если мы попробуем запустить игру сейчас, то Unity оповестит о том, что не знает, где Lerpz должен быть перерожден. Это то самое место, где в дело вступают точки перерождения…

Точки перерождения

Когда игрок погибает, нам нужно какое-то безопасное место для его повторного появления. В данном уроке Lerpz будет снова появляться в одной из трех точек перерождения. Когда Lerpz соприкасается с одной из точек, то она становится активной и это будет то место, где Lerpz переродится, если погибнет.

alt
Lerpz, стоящий на активированной точке перерождения.

Точки перерождения — это экземпляры объекта-префаба RespawnPrefab. (Вы найдете его в папке Props, в окне «Project».)

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

  • RSBase содержит саму модель: короткое цилиндрическое основание с сияющим голубым диском в центре.
  • RSSpotlight — объект подсветки, который светит слегка уловимым голубым светом на поверхность модели, создавая иллюзию того, что голубая текстура светится.
  • Остальные игровые объекты — системы частиц. Скрипт Respawn, прикрепленный к родительскому объекту RespawnPrefab,переключается между двумя системами частиц в зависимости от состояния префаба:
    • Если точка перерождения неактивна, маленький слегка уловимый эффект частиц, отображающийся в виде ярко-голубого тумана. Он содержится в RsParticlesInactive.
    • Если точка перерождения активирована, отображается намного более показным эффектом.p Он содержится в RsParticlesActive.
      Только одна точка перерождения в уровне может быть активирована одновременно. Когда игрок соприкасается с точкой перерождения, объект-коллайдер (установленный на integer) обнаруживает его и активирует точку перерождения.
    • Остальные три системы частиц — RSParticlesRespawn1, RSParticlesRespawn2 и RSParticlesRespawn3 — включаются вместе, когда игрок перерождается на точке перерождения. Они являются однократными системами частиц. Скрипт позволяет им проигрываться, затем сохраняет систему частиц RsParticlesActive как только однократная последовательность кадров была завершена.

Префаб содержит скрипт Respawn, который управляет состоянием точки перерождения. Тем не менее, для того, чтобы игра знала, в какую конкретно точку перерождения нужно возвратить игрока, в случае его гибели, мы должны распределить точки перерождения в иерархии под скриптом master controller. Давайте сделаем это сейчас:

  • Перетащите RespawnPrefab в окно сцены.
  • Расположите его как показано на изображении, на следующей странице.
  • Переименуйте этот экземпляр в Respawn1.
  • Повторите вышеописанные шаги еще два раза. Вы можете разместить их там, где пожелаете — добавьте их еще, если хотите! Я предлагаю добавить одну рядом с ареной в дальнем конце уровня, а другую рядом с деревьями в саду, выше платформ.

Следующий шаг — создать контейнер GameObject.

  • Переименуйте его в RespawnPoints.
  • Сделайте все экземпляры префаба respawm детьми для RespawnPoints.
alt
Размещение первой точки перерождения. (Lerpz был отодвинут для наглядности.)

Как это работает

Когда Сцена загружается, Unity вызывает функцию Start() в каждом экземпляре скрипта Respawn, где инициализируются некоторые полезные переменные и кэшируются указатели на другие элементы.

Ключевой механизм сконцентрирован вокруг переменной static:

//Это некоторый код скрипта
static var currentRespawn: Respawn;

Она определяет глобальную переменную с именем currentRespawn.

Ключевое слово static означает, то что переменная распределяется между всеми экземплярами скрипта. Это позволяет нам отслеживать какая точка перерождения является текущей и активной. Тем не менее, когда запускается сцена, ни одна из точек не активирована, поэтому нам нужно установить одну по умолчанию для всей Сцены. Инспектор Unity не отображает типы статичных переменных вообще, поэтому скрипт определяет свойство Initial Respawn, которое должно быть установлено для каждого экземпляра.

  • Перетащите Respawn1 на пункт «Initial Respawn» в окне «Inspector».
  • Вам нужно будет повторить проделанное для всех точек перерождения в сцене. В случае проекта данного урока, значение по умолчанию установлено на Respawn1 в каждом экземпляре префаба respawn. Respawn1 расположен рядом с тюрьмой и прямо под стартовой точкой игрока.
Примечание Невозможно установить данные свойства напрямую в оригинальном префабе.

Когда точка перерождения активируется игроком, запускающим ее коллайдер, то скрипт Respawn этой точки сначала деактивирует старую точку перерождения, а затем устанавливает значение currentRespawn для того, чтобы указать на себя. Функция SetActive() заботится о том, чтобы запускались соответствующие системы частиц и звуковые эффекты.

Перерождение персонажа игрока обслуживается скриптом ThirdPersonStatus, который управляет большей частью его игрового состояния.

  • Добавьте скрипт ThirdPersonStatus игровому объекту Player. Скрипт можно найти в Scripts -> Player -> ThirdPersonStatus.

Скрипты точек перерождения также обрабатывают звуковые эффекты. Они проигрываются как однократные сэмплы, за исключением Audio Source , который присоединен к каждому префабу Respawn. Этот компонент содержит «активный» звук, который «циклически» проигрывается. Скрипт просто включает или отключает этот звук по мере необходимости, либо проигрывает однократный эффект — например, когда игрок в действительности перерождается или активируется на самой точке перерождения — или когда перерождение было деактивировано.

Примечание Unity позволяет практически также легко добавлять звуковые эффекты. Всякий раз, когда вы планируете добавить подобные ресурсы, продумайте тщательно, как они будут использоваться. Например, мы не добавили звук «respawn deactivated» , потому что вы никогда не услышите этот проигрываемый звук; вы вряд ли расположите две точки перерождения в одном пределе слышимости друг от друга. Если бы вы преобразовали проект в мультиплеерную игру, то вы могли бы захотеть добавить такой звук и необходимый код скрипта, который бы управлял им.

Скрипт не сложный и вы бы обнаружили, что его код достаточно прост в работе. Мы вернемся к точкам перерождения в последующих главах.

Смотрите также:

Урок по созданию трехмерной игры-платформера в среде разработки Unity3D: Введение


Урок по созданию трехмерной игры-платформера в среде разработки Unity3D: Настройка сцены

Комментировать

Почта не публикуется.Обязательные поля отмечены *