Уроки Unity 3d

Как сделать похожую на Jetpack Joyride игру с помощью Unity 2D — часть 3

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

Jetpack-feature

Версия

Unity 2017.x, Unity

Это заключительная часть серии уроков, состоящей из трех частей о том, как создать игру, подобную Jetpack Joyride, в Unity 2D. Если вы пропустили предыдущие части, вам следует вернуться назад и сначала пройти часть 1 и часть 2.

В этой части вы добавите лазеры, монеты, звуковые эффекты и музыку.

Введение

Вы можете продолжить этот урок, используя проект, который вы создали в конце второй части. Кроме того, вы можете скачать финальный проект RocketMouse Part 2 по ссылке в нижней части этого руководства.

Откройте сцену RocketMouse.unity и приступайте к работе!

Добавление лазеров

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

Создание лазера

Вам нужно повторить следующие шаги, чтобы создать препятствие в виде лазера:

  1. В окне «Project» найдите спрайт laser_on, который находится в папке «Sprites» и перетащите его в рабочую область. Поскольку префаб лазера состоит только из одного объекта, вам не нужно размещать его в начале координат.
  2. Выберите laser_on в меню Hierarchy и переименуйте его в laser.
  3. Установите для Sprite Renderer Sorting Layer значение Objects.
  4. Добавьте компонент Box Collider 2D.
  5. Включите свойство Is Trigger в компоненте Box Collider 2D.

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

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

  1. Установите размер коллайдера: X = 0,18 и Y = 3,1. Таким образом коллайдер будет находиться только там, где находится сам лазер.
  2. Создайте новый скрипт C# с именем LaserScript и прикрепите его к вашему лазеру.

Вот как это должно выглядеть на примере:

Включение и выключение лазера

Откройте LaserScript и добавьте следующие переменные:

//1

public Sprite laserOnSprite;

public Sprite laserOffSprite;

//2

public float toggleInterval = 0.5f;

public float rotationSpeed = 0.0f;

//3

private bool isLaserOn = true;

private float timeUntilNextToggle;

//4

private Collider2D laserCollider;

private SpriteRenderer laserRenderer;

Вот что означает каждый пункт:

  1. Лазер имеет два состояния: включено и выключено, и для каждого состояния имеется отдельное изображение.
  2. Эти свойства позволяют добавить немного случайных колебаний. Вы можете установить другое значение toggleInterval, чтобы все лазеры на уровне не работали одинаково. Устанавливая низкий интервал, вы создаете лазер, который будет быстро включаться и выключаться, а путем установки высокого интервала вы создадите лазер, который будет оставаться в одном состоянии в течение некоторого времени. Переменная RotationSpeed служит аналогичной цели и определяет скорость вращения лазера.
  3. Эти переменные используются для переключения состояния лазера.
  4. Эти переменные содержат ссылки на лазерный коллайдер и рендерер, так что их свойства можно регулировать.

Вот пример различных конфигураций лазера, каждый из которых имеет разные значения toggleInterval и rotationSpeed:

Добавьте следующий код в метод Start:

//1

timeUntilNextToggle = toggleInterval;

//2

laserCollider = gameObject.GetComponent<Collider2D>();

laserRenderer = gameObject.GetComponent<SpriteRenderer>();
  1. Это установит время, в течение которого лазер должен переключиться в изначальное состояние в первый раз.
  2. Здесь хранятся ссылки на коллайдер и рендерер и вам нужно будет настроить их свойства для каждого временного отрезка.

Для переключения и вращения лазера добавьте следующее в метод Update:

//1

timeUntilNextToggle -= Time.deltaTime;

//2

if (timeUntilNextToggle <= 0)

{

    //3

    isLaserOn = !isLaserOn;

    //4

    laserCollider.enabled = isLaserOn;

    //5

    if (isLaserOn)

    {

        laserRenderer.sprite = laserOnSprite;

    }

    else

    {

        laserRenderer.sprite = laserOffSprite;

    }

    //6

    timeUntilNextToggle = toggleInterval;

}

//7

transform.RotateAround(transform.position, Vector3.forward, rotationSpeed * Time.deltaTime);

Вот что делает этот код:

  1. Уменьшает время, оставшееся до следующего переключения.
  2. Если timeUntilNextToggle равно или меньше нуля, изменяется текущее состояние лазера.
  3. Устанавливается правильное состояние лазера в приватной переменной.
  4. Лазерный коллайдер включается только при активном лазере. Это означает, что мышь может свободно проходить сквозь поле лазера, если он выключен.
  5. Устанавливается правильный лазерный спрайт в зависимости от состояния лазера. Отображается спрайт laser_on, когда лазер включен, и спрайт laser_off, когда он выключен.
  6. Идет сброс переменной timeUntilNextToggle.
  7. Перемещает лазер вокруг оси Z, используя данные скорости его вращения.

Примечание: чтобы отключить вращение, вы можете установить значение rotationSpeed = 0.

Изменение параметров скрипта лазера

Вернитесь в Unity и выберите laser в Hierarchy. Убедитесь, что компонент Laser Script является видимым.

Перетащите спрайт laser_on из Project в Laser On Sprite компонента Laser Script в меню Inspector.

Затем перетащите спрайт laser_off в Laser Off Sprite.

Установите значение параметра Rotation Speed = 30.

Теперь координаты для лазера на (2, 0,25, 0), чтобы проверить, все ли правильно работает. Запустите сцену, и вы увидите, что лазер вращается так, как нужно.

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

Просто: перетащите объект laser в папку «Prefabs» окна «Project», как показано на изображении ниже.

Убийство мыши

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

Откройте скрипт MouseController и добавьте новую переменную для isDead:

private bool isDead = false;

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

Теперь добавьте следующие два метода для класса MouseController:

void OnTriggerEnter2D(Collider2D collider)

{

    HitByLaser(collider);

}




void HitByLaser(Collider2D laserCollider)

{

    isDead = true;

}

Метод OnTriggerEnter2D вызывается, когда мышь сталкивается с любым лазером. Сейчас он помечает мышь как мертвый объект.

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

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

bool jetpackActive = Input.GetButton("Fire1");

jetpackActive = jetpackActive && !isDead;




if (jetpackActive)

{

    playerRigidbody.AddForce(new Vector2(0, jetpackForce));

}




if (!isDead)

{

    Vector2 newVelocity = playerRigidbody.velocity;

    newVelocity.x = forwardMovementSpeed;

    playerRigidbody.velocity = newVelocity;

}




UpdateGroundedStatus();

AdjustJetpack(jetpackActive);

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

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

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

Добавление анимации падения и гибели мыши

Выберите GameObject в меню Hierarchy и откройте окно «Animation». Создайте новый клип под названием die и сохраните новую анимацию в папку «Animations».

После этого выполните следующие шаги:

  1. Откройте папку «Sprites» в окне «Project».
  2. Выберите и перетащите спрайты mouse_die_0 и mouse_die_1 в область Animation timeline.
  3. Установите Samples на 8, чтобы замедлить анимацию.

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

Выберите объект mouse в Hierarchy

В окне «Animation» выберите команду «Create New Clip…»

Создайте новую анимацию с именем fall и сохраните ее в папке Animations.

Убедитесь, что папка Sprites открыта в окне Project, и перетащите mouse_fall из mouse_sprite_sheet на временную шкалу Animation.

Переход к анимации падения и смерти

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

Откройте окно Animator и создайте новый параметр Bool с именем isDead.

Далее создайте новый переход от Any State до fall.

Выберите этот переход и в меню Conditions установите для isDead значение true. Добавьте isGounded в качестве второго параметра, нажав кнопку +, и установите для него значение false.

Далее создайте новый переход от Any State до die. Выберите этот переход и в меню Conditions установите для обоих параметров isDead и isGounded значения true.

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

  1. Умер в воздухе.
  2. Умер на земле.

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

Теперь вам нужно обновить параметр isDead из скрипта MouseController. Откройте скрипт MouseController и добавьте следующую строку в конец метода HitByLaser:

mouseAnimator.SetBool("isDead", true);

Это установит для параметра isDead компонента Animator значение true. Запустите сцену и попробуйте попасть в зону действия лазера.

Когда мышь касается лазера, сценарий устанавливает для параметра isDead значение true, а мышь переключается в состояние падения. Однако, когда мышь достигает пола, сценарий также устанавливает для параметра isGounded значение true. Посмотрите, сейчас бедная мышь постоянно пытается «восстать» из мертвых.

Настройка триггера для анимации смерти

В режиме воспроизведения щелкните мышкой в области окна «Animator» и вы увидите, что действие смерти на данный момент повторяется многократно.

Чтобы это исправить, вы можете использовать специальный тип параметра, называемый Trigger. Параметры триггера очень похожи на Bools, за исключением того, что они автоматически сбрасываются после использования.

Откройте окно Animator и добавьте новый параметр Trigger под названием dieOnceTrigger. Установите его состояние на On, выбрав переключатель рядом с ним.

Затем выберите переход из Any State в die и добавьте dieOnceTrigger в раздел Conditions, как показано на изображении ниже.

Затем откройте папку Animations в каталоге RW и выберите die. Чтобы убрать зацикливание анимации в окне Inspector снимите флажок с Loop Time.

Запустите сцену и снова попробуйте пересечь лазерный луч.

На этот раз мышь выглядит гораздо спокойнее!

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

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

Создание префаба для монет

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

  • Не нужно создавать отдельный сценарий для монеты.
  • Используйте Circle Collider 2D вместо Box Collider 2D.
  • Включите опцию Is Trigger для коллайдера.

Вы также можете воспользоваться подсказкой ниже:

  1. Откройте папку «Sprites» в окне «Project».
  2. Перетащите спрайт на сцену и выберите его в меню Hierarchy.
  3. В Инспекторе установите его Сортировочный слой на Объекты.
  4. Добавьте компонент CircleCollider2D.
  5. Включите свойство Is Trigger для коллайдера.
  6. Установите значение Radius = 0,23.

Вот как это выглядит:

После создания GameObject для монет перетащите его из меню Hierarchy в папку Prefabs, чтобы создать префаб для монет.

Теперь добавьте несколько монет в игровую сцену, чтобы получилось примерно так:

Запустите сцену и попробуйте собрать монетки.

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

Использование тегов

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

Выберите префаб монет в папке Prefabs и откройте их свойства в меню Inspector. Вам нужно нажать на раскрывающееся меню и выбрать команду Add Tag…:

Таким образом перед вами появится окно редактора Tags & Layers в разделе Inspector. В разделе Tags добавьте тег с именем Coins. Теперь снова выберите coin Prefab в окне Project и установите для него тег Coins в меню Inspector.

Обновление скрипта MouseController

Откройте скрипт MouseController и добавьте новую переменную для создания счетчика монет:

private uint coins = 0;

Тут будет храниться информация о количестве монет.

Теперь добавьте метод CollectCoin:

void CollectCoin(Collider2D coinCollider)

{

    coins++;

    Destroy(coinCollider.gameObject);

}

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

Внесите следующие изменения в метод OnTriggerEnter2D:

if (collider.gameObject.CompareTag("Coins"))

{

    CollectCoin(collider);

}

else

{

    HitByLaser(collider);

}

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

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

Запустите сцену:

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

Генерация объектов

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

Создание конфигурации для группы монет

Откройте папку Prefabs в окне Project и перетащите 9 монет на сцену, используя префабы монет. Это должно выглядеть примерно так:

Выберите любую монету и установите координаты для Position в (0, 0, 0). Это будет центральная монета. Вам нужно добавить все монеты в Empty GameObject, поэтому вам потребуется построить свою фигуру вокруг начала координат.

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

Теперь создайте Empty GameObject, выбрав GameObjectCreate Empty и переименуйте его в coins_v.

Установите координаты для Position на (0, 0, 0), выберите все монеты в Hierarchy и добавьте их в coins_v. Вот, что у вас должно получиться:

Выберите coins_v в меню Hierarchy и перетащите его в папку «Prefabs» в окне «Project», чтобы создать новый префаб для генерации монет.

Примечание: вы можете создать столько разных комбинаций монет, сколько пожелаете.

Добавление новых параметров в GeneratorScript

Откройте GeneratorScript и добавьте следующие переменные:

public GameObject[] availableObjects;

public List<GameObject> objects;




public float objectsMinDistance = 5.0f;

public float objectsMaxDistance = 10.0f;




public float objectsMinY = -1.4f;

public float objectsMaxY = 1.4f;




public float objectsMinRotation = -45.0f;

public float objectsMaxRotation = 45.0f;

Раздел availableObjects будет содержать все объекты, которые может сгенерировать скрипт (то есть разные фигуры из монет и лазерные поля).

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

Добавление метода для добавления нового объекта

Новые объекты добавляются в методе AddObject аналогично тому, как добавляются комнаты. Добавьте следующие данные в GeneratorScript:

void AddObject(float lastObjectX)

{

    //1

    int randomIndex = Random.Range(0, availableObjects.Length);

    //2

    GameObject obj = (GameObject)Instantiate(availableObjects[randomIndex]);

    //3

    float objectPositionX = lastObjectX + Random.Range(objectsMinDistance, objectsMaxDistance);

    float randomY = Random.Range(objectsMinY, objectsMaxY);

    obj.transform.position = new Vector3(objectPositionX,randomY,0);

    //4

    float rotation = Random.Range(objectsMinRotation, objectsMaxRotation);

    obj.transform.rotation = Quaternion.Euler(Vector3.forward * rotation);

    //5

    objects.Add(obj);           

}

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

Генерация и удаление объектов

Добавьте следующие данные в GeneratorScript:

void GenerateObjectsIfRequired()

{

    //1

    float playerX = transform.position.x;

    float removeObjectsX = playerX - screenWidthInPoints;

    float addObjectX = playerX + screenWidthInPoints;

    float farthestObjectX = 0;

    //2

    List<GameObject> objectsToRemove = new List<GameObject>();

    foreach (var obj in objects)

    {

        //3

        float objX = obj.transform.position.x;

        //4

        farthestObjectX = Mathf.Max(farthestObjectX, objX);

        //5

        if (objX < removeObjectsX)

        {          

            objectsToRemove.Add(obj);

        }

    }

    //6

    foreach (var obj in objectsToRemove)

    {

        objects.Remove(obj);

        Destroy(obj);

    }

    //7

    if (farthestObjectX < addObjectX)

    {

        AddObject(farthestObjectX);

    }

}

Чтобы этот метод работал, вам также нужно добавить команду GenerateObjectsIfRequired в пункт GeneratorCheck, который находится немного ниже GenerateRoomIfRequired:

GenerateObjectsIfRequired();

Настройка параметров скрипта

Чтобы заставить GeneratorScript работать, вам нужно установить несколько параметров для него. Вернитесь в Unity и выберите GameObject в окне Hierarchy.

Найдите компонент «Generator Script» в меню Inspector и убедитесь, что папка «Prefabs» открыта в окне Project.

Перетащите префаб coins_v из окна Project в список «Available Objects», который находится в компоненте GeneratorScript. Затем таким же образом перетащите префаб laser из окна Project в список «Available Objects».

Запустите сцену и посмотрите, что получилось:

Добавление элементов графического интерфейса

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

Отображение количества монет

Откройте скрипт MouseController и добавьте пункт UnityEngine.UI, чтобы использовать возможности новой графической системы Unity.

using UnityEngine.UI;

Вернитесь в Unity, чтобы начать создание пользовательского интерфейса. Нажмите GameObject UI Image, чтобы добавить элемент Image.

Если это первый элемент пользовательского интерфейса в вашей сцене, Unity автоматически создаст несколько объектов для начала работы с ним: Canvas и EventSystem. Обратите внимание, новый элемент Image является дочерним элементом рабочей области. EventSystem отвечает за обработку raycast и обработку связанных событий.

 

Теперь нажмите GameObject UI Text, чтобы добавить элемент Text.

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

Выберите Image Object в меню Hierarchy и переименуйте его в coinImage в окне Inspector. Пользовательский интерфейс Unity использует уникальный компонент Rect Transform, более ориентированный на 2D изображения. Кроме того, Rect Transform дополнительно предоставляет параметры для управления размером, привязкой и точкой поворота ваших элементов пользовательского интерфейса.

Примечание: для более глубокого понимания системы пользовательского интерфейса рекомендуется взглянуть на учебник Введение в Unity.

Посмотрите на поле в левом верхнем углу компонента Rect Transform. Оно представляет точку привязки и точку поворота вашего элемента пользовательского интерфейса. Нажатие на это поле, чтобы появилось меню опций под названием «Anchor Presets». Вы можете удерживать Shift чтобы повернуть элемент, и Alt, чтобы установить его положение. Теперь вы можете приступить к детальной настройке элемента.

  1. Нажмите поле Anchor Preset, удерживая клавиши «Alt» и «Shift», щелкните на верхнее левое поле в сетке.

  1. Установите Pos X на 15, а Pos Y на -15.
  2. Отрегулируйте высоту и ширину до 70.
  3. В окне inspector вы можете установить спрайт, который вы хотите отображать в компоненте Image. Это должно выглядеть следующим образом:

  1. Выберите объект Text в меню Hierarchy и перетащите его в coinImage. Чтобы сделать объект Text дочерним нужно:
  2. В окне inspector переименовать объект в coinsCollected.
  3. Щелкнуть на поле «Anchor Preset» и, удерживая нажатой клавишу «Alt» и «Shift», щелкнуть в левой части средней сетки

  1. Установите Pos X на 75, и height = 70, как показано на изображении ниже:

Внесите следующие изменения в компонент Text:

  1. Измените данные в поле Text на 0.
  2. Увеличьте размер шрифта до 60.
  3. В свойстве Alignment измените верхнее вертикальное выравнивание на среднее.
  4. Измените Wrap на Overflow.
  5. Наконец, выберите желтый или золотой цвет для свойства цвета.

Вы уже ведете счет собранным монетам в скрипте MouseController, поэтому теперь вам необходимо подключить это значение к тексту coinsCollected.

Создайте новую переменную в MouseController:

public Text coinsCollectedLabel;

В методе CollectCoin сразу после coins ++; добавьте следующую строку кода:

coinsCollectedLabel.text = coins.ToString();

Таким образом целое число монет просто преобразуется в строку и применяется к свойству text элемента Text.

Вернувшись в Unity, перетащите элемент coinsCollected Text из меню hierarchy в coinsCollectedLabel:

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

Перезапуск игры

Теперь вам нужно создать кнопку перезагрузки. Для этого необходимо использовать еще одно пространство имен в MouseController. Откройте скрипт и добавьте следующие данные в самом вверху:

using UnityEngine.SceneManagement;

Также добавьте новый метод:

public void RestartGame()

{

    SceneManager.LoadScene("RocketMouse");

}

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

public Button restartButton;

а также код, который вы должны вписать в конец метода FixedUpdate:

if (isDead && isGrounded)

{

    restartButton.gameObject.SetActive(true);

}

Вернитесь в Unity, чтобы создать кнопку, выбрав GameObjectUI Button.

В меню Inspector переименуйте новую кнопку в restartButton. Кнопка уже должна быть хорошо отцентрирована, однако вам необходимо сделать ее немного больше. Установите ширину = 200 и высоту = 60.

Текст в кнопке является дочерним элементом кнопки. В меню Hierarchy щелкните треугольник рядом с кнопкой restartButton и выберите элемент Text.

Вернувшись в Inspector, измените текст на «Tap to restart! и установите размер шрифта = 24.

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

Выберите мышь, чтобы отобразить сценарий «Mouse Controller» в окне Inspector, и перетащите кнопку restartButton из меню Hierarchy на кнопку «Restart Button» в Mouse Controller.

Последний шаг — сообщить кнопке, какой метод выполнять при нажатии. Выберите resetButton в меню Hierarchy и в компоненте Button в окне Inspector найдите On Click (). Нажмите кнопку + и перетащите GameObject из меню Hierarchy в поле None. Нажмите на кнопку No Function и выберите MouseControllerRestartGame ().

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

Добавление звуков и музыки

Сейчас в игре нет никаких звуков, и чтобы ее оживить вам нужно это исправить.

Звук для лазера

Откройте папку Prefabs в окне Project и выберите префаб лазера.

В окне Inspector добавьте компонент «Audio Source», нажав «Add Component» и выбрав AudioAudio Source. Затем откройте папку Audio в окне Project и перетащите звук laser_zap в поле Audio Clip. Не забудьте снять флажок Play On Awake.

Вот что у вас должно получиться:

Примечание: обязательно убедитесь, что вы выбрали правильный префаб, а не экземпляр объекта.

Теперь откройте скрипт MouseController и добавьте следующий код в начало метода HitByLaser:

if (!isDead)

{

    AudioSource laserZap = laserCollider.gameObject.GetComponent<AudioSource>();

    laserZap.Play();

}

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

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

Звук сбора монет

Откройте скрипт MouseController и добавьте следующую переменную:

public AudioClip coinCollectSound;

Найдите метод CollectCoin и добавьте следующую строку кода в конце метода:

AudioSource.PlayClipAtPoint(coinCollectSound, transform.position);

Вернитесь в Unity и выберите мышью GameObject в меню Hierarchy. Перетащите звук coin_collect из окна Project в поле Coin Collect Sound в скрипте MouseController.

Запустите сцену и попробуйте собрать несколько монет.

Звуки шагов и реактивного ранца

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

Добавление Audio Sources

Выберите GameObject в меню Hierarchy и добавьте два новых компонента Audio Source. Перетащите звук footsteps шаги окна Project в поле Audio Clip первого компонента Audio Source. Затем перетащите jetpack_sound в поле Audio Clip второго компонента Audio Source.

Включите Play On Awake и Loop для обоих аудиоисточников.

Если вы сейчас запустите сцену, то вы услышите оба звука беспрерывно звучащие в одно и тоже время, не зависимо от действий персонажа.

Переключение между звуком шагов и реактивного ранца

Откройте скрипт MouseController и добавьте две новые переменные:

public AudioSource jetpackAudio;

public AudioSource footstepsAudio;

Теперь добавьте метод AdjustFootstepsAndJetpackSound:

void AdjustFootstepsAndJetpackSound(bool jetpackActive)

{

    footstepsAudio.enabled = !isDead && isGrounded;

    jetpackAudio.enabled = !isDead && !isGrounded;

    if (jetpackActive)

    {

        jetpackAudio.volume = 1.0f;

    }

    else

    {

        jetpackAudio.volume = 0.5f;

    }

}

Наконец, добавьте вызов AdjustFootstepsAndJetpackSound в конце метода FixedUpdate:

AdjustFootstepsAndJetpackSound(jetpackActive);

Задание переменных сценария «Шаг» и «полет»

Вернитесь в Unity и выберите GameObject в меню Hierachy. Теперь перетащите верхний компонент Audio Source в Footsteps Audio в скрипте Mouse Controller.

После этого перетащите второй компонент Audio Source в Jetpack Audio в компоненте скрипта Mouse Controller.

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

Добавление музыки

Чтобы добавить музыку, выполните следующие шаги:

  1. Выберите Main Camera в меню Hierachy.
  2. Добавьте компонент Audio Source в окне Inspector.
  3. Перетащите звук музыки из покна Project в свойство Audio Clip.
  4. Убедитесь, что Play On Awake и Loop включены.
  5. Наконец, уменьшите громкость до 0,3, чтобы музыка не была слишком громкой по сравнению с другими звуками.

Добавление параллакс эффекта для фона

В настоящее время задний фон довольно обычный.

Однако вы можете разнообразить его двумя способами:

  • Создать вид за окном.
  • Убрать окна.

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

Подготовка фоновых изображений

Чтобы использовать фоновые изображения, вам необходимо настроить способ их импорта в Unity.

Откройте папку Sprites в окне Project и выберите window_background. В окне Inspector измените Texture Type на Default вместо Sprite (2D и UI). После этого измените Wrap Mode на Repeat и нажмите Apply.

Сделайте то же самое для изображения window_foreground.

Создание еще другой камеры

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

Создайте новую камеру, выбрав GameObjectCamera и выбрав ее в окне Hierarchy и внесите следующие изменения:

  1. Измените название на ParallaxCamera.
  2. Установите Position в (0, 10, 0).
  3. Установите Projection на Orthographic.
  4. Установите такой же размер, как у основной камеры = 3,2.

Поскольку у вас есть две камеры, у вас также есть два аудио слушателя на игровой сцене. Отключите параметр Audio Listener в ParallaxCamera:

Создание четырехугольников

Создайте два объекта Quad, выбрав GameObject3D Object ⇒ Quad. Назовите первый четырехугольник parallaxBackground а второй parallaxForeground. Перетащите оба квадрата в ParallaxCamera, чтобы добавить их как дочерние объекты камеры.

Выберите parallaxBackground и измените значение Position на (0, 0,7, 10), а Scale на (11,36, 4,92, 1).

Выберите parallaxForeground и установите Position в (0, 0,7, 9) и Scale в (11,36, 4,92, 1).

Установка текстуры для четырехугольников

Откройте папку Sprites в окне Project и перетащите window_background на parallaxBackground и window_foreground на parallaxForeground в меню Hierarchy.

Теперь вам нужно в меню Hierarchy выбрать parallaxForeground. Вы увидите, что был добавлен компонент Mesh Renderer. Нажмите на раскрывающееся меню Shader и выберите UnlitTransparent.

Сделайте то же самое для parallaxBackground.

Вот что у вас должно получиться в конечном итоге:

Если вы отключите режим 2D и немного повернете сцену, то увидите, как все располагаются все компоненты сцены.

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

Создание текстуры

Теперь вы создадите имитацию движения фона за окном, изменяя смещение текстуры.

Создайте новый скрипт C# под названием ParallaxScroll и прикрепите его к ParallaxCamera.

Откройте скрипт ParallaxScroll и добавьте следующие переменные:

//1

public Renderer background;

public Renderer foreground;

//2

public float backgroundSpeed = 0.02f;

public float foregroundSpeed = 0.06f;

//3

public float offset = 0.0f;

Вот, что делают эти переменные:

  1. Переменные Renderer будут содержать ссылку на компонент Mesh Renderer каждого из четырехугольников, чтобы вы могли настроить их текстуры.
  2. BackgroundSpeed и foregroundSpeed определяют скорость движения для каждого фона.
  3. Смещение будет обеспечиваться положением игрока. Это позволит вам связать движение мыши с движением фона параллакса.

Добавьте следующий код в метод Update:

float backgroundOffset = offset * backgroundSpeed;

float foregroundOffset = offset * foregroundSpeed;




background.material.mainTextureOffset = new Vector2(backgroundOffset, 0);

foreground.material.mainTextureOffset = new Vector2(foregroundOffset, 0);

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

Вернитесь в Unity и выберите ParallaxCamera в меню Hierarchy. Перетащите квадратик parallaxBackground в поле «Background» скрипта ParallaxScroll и переместите parallaxForeground на передний план.

Теперь откройте скрипт MouseController и добавьте следующую переменную:

public ParallaxScroll parallax;

Затем добавьте следующий код в конец метода FixedUpdate:

parallax.offset = transform.position.x;

Вернитесь в Unity и выберите GameObject в меню Hierarchy. Убедитесь, что скрипт MouseController виден в окне Inspector.

Перетащите ParallaxCamera из меню Hierarchy в поле Parallax в окне Inspector.

Это позволит сценарию MouseController изменить переменную смещения сценария ParallaxScroll относительно положения персонажа.

Запустите сцену, чтобы посмотреть, как эффект параллакса.

Установка порядка камер

Выберите ParallaxCamera в меню Hierarchy. В окне Inspector найдите компонент «Camera» и найдя поле «Depth», установите его значение = -2.

Примечание: глубина ParallaxCamera должна быть ниже, чем глубина основной камеры.

Однако, если вы запустите игру прямо сейчас, вы не увидите фон параллакса в окне.

Чтобы это исправить, выберите Main Camera в меню Hierarchy и установите для Clear Flags значение Depth Only.

Запустите сцену – теперь в окне должно быть видно фон параллакса.

Что делать дальше?

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

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

Перевод
Оригинал на англ.
Показать еще
Back to top button