Статьи

Создайте гоночную игру на воздушном шаре в Unity с помощью микрофона

Конечный продукт
Что вы будете создавать

В этом уроке вы узнаете, как создать 2D-игру, используя C # и Unity. Мы будем использовать поддержку микрофона Unity для улучшения игрового процесса в игре. Цель игры проста, достигнуть другой стороны уровня, избегая препятствий на пути. Игрок может перемещать главного героя, дуя на микрофон устройства, перемещая его вверх.

В этом уроке вы узнаете следующие аспекты разработки игр для Unity:

  • настройка 2D проекта в Unity
  • импорт спрайтов
  • управление микрофоном
  • работа с физическими столкновениями

Откройте Unity и выберите « Новый проект» в меню « Файл», чтобы открыть диалоговое окно нового проекта. Сообщите Unity, где вы хотите сохранить проект, и установите   Установите значения по умолчанию для: меню в 2D .

На следующем шаге вам будет представлен пользовательский интерфейс Unity. Настройте проект на предпочитаемую платформу, выбрав « Настройки сборки» в меню « Файл» и выбрав целевую платформу.

Прежде чем начать, убедитесь, что кнопка 2D на панели « Сцена» выделена. Вы также можете изменить текущее разрешение на панели « Игра» .

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

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

Вы можете использовать один из трех языков программирования при использовании Unity, C # , UnityScript , разновидности JavaScript и Boo . Каждый из этих языков программирования имеет свои плюсы и минусы, и вам решать, какой из них вы предпочитаете. Мои личные предпочтения относятся к языку программирования C #, и этот язык я буду использовать в этом руководстве.

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

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

  • выберите Импортировать новый актив в меню Активы
  • добавить элементы в папку активов в вашем проекте
  • перетащите активы в окно проекта

После выполнения этого шага вы должны увидеть активы в папке « Ресурсы » вашего проекта на панели « Проект» .

Мы будем использовать несколько звуков, чтобы создать отличный звуковой опыт. Звуковые эффекты, используемые в этом руководстве, были получены с сайта freesound.org .

Начните с перетаскивания фона на панель Иерархия . Он должен автоматически появиться на панели « Сцена» .

Поскольку панель « Сцена» настроена на отображение 2D-вида, вы заметите, что при выборе основной камеры в иерархии отображается предварительный просмотр того, что будет отображаться камерой. Вы также можете увидеть это в представлении игры . Чтобы сделать всю сцену видимой, установите значение « Размер» основной камеры на 4 на панели « Инспектор», как показано ниже.

Мы будем использовать спрайт-лист для элементов пользовательского интерфейса нашей игры. В Unity есть редактор спрайтов, который позволяет легко использовать спрайты. Иллюстрации, использованные в этом уроке, были получены с openclipart.org .

Импортируйте иллюстрацию, выберите ее на панели « Активы» и измените параметр « Режим спрайта» на « Несколько» на панели « Инспектор» .

Нажмите кнопку с надписью Sprite Editor и установите для параметра « Тип» значение « Автоматический» .

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

Для обнаружения столкновений по крайней мере один из сталкивающихся объектов должен иметь прикрепленный к нему 2D- компонент Rigidbody . Чтобы добавить его в корову, нажмите кнопку « Добавить компонент» на панели « Инспектор» . Из списка компонентов выберите RigidBody 2D в разделе Physics 2D .

Установите флажок Фиксированный угол, чтобы корова не вращалась в случае столкновения. Мы не будем использовать физическую гравитацию по умолчанию в этой игре, вместо этого мы будем имитировать нашу собственную. Измените шкалу гравитации с 1 на 0, чтобы сила тяжести по умолчанию не влияла на объект.

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

Чтобы пол определял, когда персонаж касается его, нам нужно добавить компонент Box Collider 2D . Коллайдер — это физическая форма, которая определяет область, которая вызывает столкновение.

Выберите основной игровой объект в Иерархии , откройте панель « Инспектор» и нажмите « Добавить компонент» . Из списка компонентов выберите Box Collider 2D в разделе Physics 2D .

Измените свойство Size на X: 4.8 и Y: 0.05, чтобы создать маленький прямоугольник, в котором будет расположена корова. Наконец, добавьте Box Collider 2D к объекту игры коровы, повторив эти шаги.

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

Чтобы воспроизвести звук, когда проигрыватель собирает звезду, нам сначала нужно прикрепить к нему компонент Audio Source . Выберите звезду в представлении « Иерархия» или « Сцена» , нажмите кнопку « Добавить компонент» на панели « Инспектор» и выберите « Источник звука» в разделе « Аудио ».

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

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

Перетащите всплывающий спрайт из Активов на панель « Иерархия» и затем вернитесь в Активы . Это создаст сборный шар. Вы заметите, что текст становится синим, указывая на то, что он теперь является сборным. Создавая сборный дом, мы можем повторно использовать всплывающее окно без использования дополнительных ресурсов.

Выберите новый префаб и нажмите Ctrl + D, чтобы продублировать его. Используйте инструмент « Поворот» , чтобы немного повернуть воздушные шары, как показано на скриншоте выше.

Мы группируем корову и воздушные шары, чтобы сделать их немного легче. Для этого перетащите воздушный шар с панели « Иерархия» и поместите его поверх игрового объекта «Корова» на панели « Иерархия» . Объект игры в корову подсвечивается, чтобы указать, что падение шарика добавит его в качестве потомка объекта игры в корову. В результате перемещение объекта игры коровы также перемещает положение воздушных шаров.

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

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

Нам также нужно добавить коллайдер в каждую руку, чтобы обнаружить столкновения. Чтобы добавить коллайдер, нажмите кнопку « Добавить компонент» на панели « Инспектор» и выберите Box Collider 2D в разделе « Физика 2D ». Вы заметите, что зеленая рамка появляется вокруг руки, когда вы выбираете ее, чтобы указать, что к руке привязан коллайдер.

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

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

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

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

Это поместит звезду на вершину уровня. Чтобы определить, когда корова собирает звезду, нам нужно добавить к ней коллайдер, как мы делали это уже несколько раз. Добавьте Box Collider 2D к звезде.

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

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

Unity включает в себя редактор кода, версию Mono Develop . Хотя это хороший редактор, вы можете использовать любой редактор, который вам нравится. Visual Studio , например, является популярным выбором, если вы используете Windows.

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

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

К счастью, мы можем использовать сторонний скрипт , который даст нам доступ к свойству loudness . Свойство loudness позволит нам вместе с transform.position перемещать корову.

Создайте пустой GameObject и назовите его MicrophoneInput . Используйте кнопку « Добавить компонент» , чтобы прикрепить вышеупомянутый сценарий и компонент Audio Source к новому игровому объекту.

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

Следующий скрипт определяет класс Hand и управляет движением рук. Руки непрерывно двигаются слева направо и наоборот. Посмотрим, как это работает.

Первое свойство, которое мы используем в скрипте, это moveSpeed , число с float которое определяет количество единиц, которые рука перемещает за каждый кадр. Он устанавливает значение x свойства transform.position , перемещая руку горизонтально.

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

1
2
3
4
5
6
7
8
using UnityEngine;
using System.Collections;
 
public class Hand : MonoBehaviour
{
    private float moveSpeed = 0.02f;
    private float currentPos;
    public bool left = false;

Наконец, свойство left типа boolean определяет, движется ли стрелка влево. Это позволяет легко изменить направление руки, установив для left переменной значение true или false .

Метод Start — это метод, определенный в классе MonoBehaviour который вызывается во время инициализации перед MonoBehaviour любого другого метода, за исключением Awake , который мы не рассмотрим в этом руководстве.

В методе Start мы можем настроить объект до запуска любого другого кода. В этом случае мы устанавливаем свойство currentPos в текущую позицию руки до ее перемещения.

1
2
3
4
void Start()
{
    currentPos = transform.position.x;
}

В методе Update мы проверяем, является ли стрелка левой или правой, и перемещаем ее в правильном направлении в течение каждого кадра. Для этого мы пишем оператор if внутри метода Update и уменьшаем или увеличиваем позицию x, используя переменную moveSpeed чтобы изменить свойство position .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void Update()
{
    /* Move Hand */
 
    /* Move to the right if hand is on the left side */
 
    if (!left)
    {
        transform.position -= new Vector3(moveSpeed, 0, 0);
    } else
    {
        transform.position += new Vector3(moveSpeed, 0, 0);
    }
 
    /* Change moveSpeed to move in the other direction, creating a movement loop */
 
    if (transform.position.x <= currentPos — 0.7f)
    {
            moveSpeed *= -1;
    }
    if (transform.position.x >= currentPos + 0.7f)
    {
        moveSpeed *= -1;
    }
}
}

Когда стрелка перемещается на 0.7 единицы, мы умножаем свойство moveSpeed на -1 чтобы рука двигалась в противоположном направлении. В результате руки движутся от одной стороны к другой в непрерывном цикле, что затрудняет прохождение коровы через руки и достижение звезды.

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

01
02
03
04
05
06
07
08
09
10
11
12
using UnityEngine;
using System.Collections;
 
public class Cow : MonoBehaviour
{
    private Vector3 gravity = new Vector3(0, 0.02f, 0);
    public GameObject micVolume;
    private float moveSpeed;
    private byte balloons = 3;
    public GameObject alertWin;
    public GameObject alertLose;
}
  • gravity : используется для симуляции вертикальной силы, она тянет корову вниз
  • micVolume : ссылка на игровой объект MicrophoneInput
  • moveSpeed : получает значение loudness из класса MicrophoneInput
  • balloons : содержит количество воздушных шаров, это значение представляет жизни игрока
  • alertWin : ссылка на игровой объект alertWin
  • alertLose : ссылка на игровой объект alertLose

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

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

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

Чтобы переместить корову вверх, мы будем использовать метод FixedUpdate . Почему не обычный метод Update ? Этот метод является предопределенным методом MonoBehaviour который запускает каждую фиксированную частоту кадров вместо каждого кадра. Это означает, что он будет плавным, даже если текущая частота кадров будет немного низкой. Добавьте следующий блок кода в скрипт:

01
02
03
04
05
06
07
08
09
10
11
void FixedUpdate()
{
    /* Move Cow upwards based on Mic volume */
 
    moveSpeed = micVolume.GetComponent<MicrophoneInput>().loudness * 0.01f;
    transform.position = new Vector3(0, transform.position.y + moveSpeed, 0);
     
    /* Simulate our own gravity (this one doesn’t get stronger when high) */
 
    transform.position -= gravity;
}

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

Символ коровы перемещается путем увеличения значения y свойства transform.position с использованием скорости, которую мы сохранили в сохраненном в moveSpeed .

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

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

1
2
3
4
5
6
7
void OnTriggerEnter2D(Collider2D other)
{
    /* Hands Collision */
 
    if (other.name == «Hand» && transform.GetComponent<SpriteRenderer>().color.a == 1)
    {
        other.audio.Play();

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

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

1
2
3
4
5
/* Prevent from multiple collision */
 
Color alpha = new Color(1, 1, 1, 0.5f);
transform.GetComponent<SpriteRenderer>().color = alpha;
Invoke(«EnableCollision», 1);

Сначала мы создаем новый объект Color назначаем ему цвет игрового объекта и устанавливаем alpha значение равным 0.5 чтобы сделать его полупрозрачным. Затем мы SpriteRenderer доступ к игровому объекту SpriteRenderer , который позволяет нам изменять его цвет.

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

Когда корова поражена рукой, один шарик должен быть удален. Мы вызываем метод Destroy на игровом объекте с воздушными шарами. Мы используем функцию Find , потому что у нас нет ссылки на каждый из шариков.

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

1
2
3
4
/* Remove Balloon */
 
Destroy(GameObject.Find(«Balloon»));
balloons—;

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

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

Игра заканчивается, когда все воздушные шары лопнут. Чтобы проверить это, мы проверяем, равны ли balloons 0 и выводим предупреждение, если оно истинно. Мы также установили свойство y gravity на 0 и приостановили игру, установив timeScale на 0 .

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

1
2
3
4
5
6
7
8
9
/* Game Over */
 
    if(balloons == 0)
    {
        GameObject alert = Instantiate(alertLose, new Vector3(0, 0, 0), transform.rotation) as GameObject;
        gravity.y = 0;
        Time.timeScale = 0;
    }
}

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

Оператор if проверяет, действительно ли столкновение произошло с объектом «звезда», и воспроизводит звук, прикрепленный к корове, если имя верно. Затем мы удаляем звезду со сцены перед созданием оповещения. Мы также установили свойство y gravity на 0 как мы делали на предыдущем шаге.

01
02
03
04
05
06
07
08
09
10
/* Star Collision */
 
    if (other.name == «Star»)
    {
        audio.Play();
        Destroy(other.gameObject);
        GameObject alert = Instantiate(alertWin, new Vector3(0, 0, 0), transform.rotation) as GameObject;
        gravity.y = 0;
    }
}

Метод EnableCollision сбрасывает альфа-значение игрового объекта корова после того, как он был поражен рукой. Это позволит объекту игры с коровой обнаружить другое попадание. Обратите внимание, что объект Color имеет alpha 1 .

1
2
3
4
5
void EnableCollision()
{
    Color alpha = new Color(1, 1, 1, 1);
    transform.GetComponent<SpriteRenderer>().color = alpha;
}

Метод Reload использует класс Application для перезагрузки текущего уровня. Создайте новый скрипт с именем Restart , добавьте в него следующий блок кода и прикрепите его к обоим префабам предупреждений, которые мы создали ранее.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
using UnityEngine;
using System.Collections;
 
public class Restart : MonoBehaviour
{
    void Update()
    {
        if (Input.GetButton(«Fire1»))
        {
            Reload();
        }
    }
 
    void Reload()
    {
        Application.LoadLevel(Application.loadedLevel);
    }
}

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

Пришло время протестировать игру. Нажмите Command-P, чтобы играть в игру в Unity. Если все работает, как ожидалось, вы готовы к последним шагам.

Когда вы довольны своей игрой, пора выбрать « Настройки сборки» в меню « Файл» и нажать кнопку « Настройки игрока» . Это должно вызвать настройки проигрывателя на панели инспектора, где вы можете установить параметры для вашего приложения.

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

Как только ваш проект правильно настроен, пришло время вернуться к настройкам сборки и нажать кнопку « Сборка» . Это все, что нужно для создания вашей игры для тестирования и / или распространения.

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