Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Unity_в_действии_Джозеф_Хокинг_Рус.pdf
Скачиваний:
83
Добавлен:
21.06.2022
Размер:
26.33 Mб
Скачать

256      Глава 10. Звуковые эффекты и музыка

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

Создайте новый пустой объект GameObject и сделайте его дочерним по отношению к основному игровому диспетчеру. Так как у этого нового объекта будет компонент AudioSource, используемый диспетчером управления звуком, присвойте ему имя Audio. Добавьте к нему компонент AudioSource (на этот раз оставьте ползунок Spatial Blend в положении 2D, так как пользовательский интерфейс не имеет определенного положения в сцене) и добавьте в сценарий AudioManager код следующего листинга.

Листинг 10.7. Воспроизведение звуковых эффектов в диспетчере AudioManager

...

[SerializeField] private AudioSource soundSource; ¬ Ячейка переменной на панели Inspector для ссылки на новый источник звука.

...

public void PlaySound(AudioClip clip) { ¬ Воспроизводим звуки, не имеющие другого источника. soundSource.PlayOneShot(clip);

}

...

На панели Inspector появится новая ячейка переменной; перетащите на нее объект Audio. Теперь добавим звуковой эффект UI к сценарию всплывающего окна.

Листинг 10.8. Добавление звуковых эффектов в сценарий SettingsPopup

...

[SerializeField] private AudioClip sound; ¬ Ячейка на панели Inspector для ссылки на звуковой клип.

...

public void OnSoundToggle() {

Managers.Audio.soundMute = !Managers.Audio.soundMute; Managers.Audio.PlaySound(sound); ¬ Воспроизводим звуковой эффект при нажатии кнопки.

}

...

Перетащите звуковой эффект UI на ячейку переменной; я использовал 2D-звук thump. В результате щелчок на кнопке UI сопровождается этим звуком (если, конечно, вы не уменьшили его громкость до нуля!). И хотя сам UI не имеет источника звука, диспетчер AudioManager воспроизводит нужный звуковой эффект через свой источник.

Замечательно, мы настроили все звуковые эффекты! Пришло время обратить внимание на музыку.

10.4. Фоновая музыка

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

10.4. Фоновая музыка      257

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

Оптимизация в процессе загрузки выполняется методом Resources.Load(), с которым вы познакомились в главе 8. Как вы узнали, этот метод позволяет загружать ресурсы по имени — это удобный инструмент, но есть и другие причины загружать ресурсы из папки Resources. Одним из ключевых факторов является отложенная загрузка; обычно все ресурсы в Unity загружаются вместе со сценой, но это не касается ресурсов из папки Resources, ожидающих извлечения с помощью кода. В этом разделе нас интересует загрузка музыкальных клипов по требованию. В противном случае музыка займет слишком много места в памяти, причем еще до того, как ею начнут пользоваться.

ОПРЕДЕЛЕНИЕ  Загрузка по требованию (lazy-loading) означает, что загрузка файла заранее не делается, а откладывается до момента, когда этот файл понадобится. Обычно данные реагируют быстрее (например, немедленно начинается воспроизведение звука), когда они загружены заранее, но загрузка по требованию экономит память в ситуациях, когда быстрая реакция не имеет особого значения.

Второй способ решения проблемы с потреблением памяти связан с потоковой передачей музыки с диска. Как объяснялось в разделе 10.1.2, потоковая передача звука позволяет компьютеру обойтись без загрузки файла целиком. Тип загрузки указывается на панели Inspector импортированного аудиоклипа.

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

10.4.1. Воспроизведение музыкальных циклов

Для воспроизведения музыки потребуется уже знакомая вам последовательность шагов, которой мы придерживались при программировании звуковых эффектов пользовательского интерфейса (фоновая музыка также является 2D-звуком, то есть не имеет источника в сцене), поэтому мы просто повторим ее:

1.Импортируем аудиоклипы.

2.Настраиваем компонент AudioSource для использования диспетчером AudioManager.

3.Пишем код для воспроизведения аудиоклипа в диспетчере AudioManager.

4.Добавляем UI-элементы управления музыкой.

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

Шаг 1. Импорт аудиоклипов

Скачайте или запишите музыкальные треки. В прилагаемом к книге примере проекта я скачал с сайта www.freesound.org следующие композиции:

loop от пользователя by Xythe/Ville Nousiainen;Intro Synth от пользователя noirenex.

258      Глава 10. Звуковые эффекты и музыка

Перетащите файлы в Unity и отредактируйте их настройки импорта на панели Inspector. Как уже упоминалось, настройки аудиоклипов со звуковыми эффектами и с музыкой в общем случае различаются. Прежде всего, для звука со сжатием следует выбрать формат Vorbis. Напомню, что в результате сжатия размер файлов значительно уменьшается. Одновременно слегка ухудшается качество звука, но для длинных музыкальных клипов это вполне допустимый компромисс; установите ползунок Quality на отметку 50 %.

Затем нужно выбрать параметр Load Type. Еще раз напомню, что нам нужно чтение музыки с диска, а не ее полная загрузка. Выберите в меню Load Type вариант Streaming. Установите флажок Load In Background, чтобы в процессе загрузки музыки игра не останавливалась и не замедлялась.

И даже после всех этих настроек для корректной загрузки нужно еще поместить аудиофайл в нужное место. Надеюсь, вы помните, что метод Resources.Load() загружает только содержимое папки Resources. Создайте новую папку с этим именем, а внутри нее — папку Music и перетащите туда аудиофайлы, как показано на рис. 10.5.

Рис. 10.5. Музыкальные аудиоклипы, помещенные в папку Resources

Это даст возможность выполнить шаг 1.

Шаг 2. Настройка компонента audiosource для использования диспетчером управления звуком

Теперь нам нужно создать новый компонент AudioSource для воспроизведения музыки. Создайте пустой объект GameObject, присвойте ему имя Music 1 (единица появилась потому, что позднее мы добавим объект Music 2) и сделайте его дочерним по отношению к объекту Audio.

Добавьте к объекту Music 1 компонент AudioSource и отредактируйте его параметры. Сбросьте флажок Play On Awake, но установите флажок Loop; если звуковой эффект обычно проигрывается один раз, музыка воспроизводится в цикле. Ползунок Spatial Blend оставьте в положении 2D, так как музыка не привязана к конкретной точке сцены.

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

10.4. Фоновая музыка      259

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

Шаг 3. Программирование механизма воспроизведения аудиоклипов в диспетчере управления звуком

Мы настроили источник аудио Music, поэтому нужно добавить код следующего листинга в сценарий AudioManager.

Листинг 10.9. Воспроизведение музыки в диспетчере AudioManager

...

[SerializeField] private AudioSource music1Source;

[SerializeField] private string introBGMusic; Эти строки указывают имена музыкальных клипов. [SerializeField] private string levelBGMusic;

...

public void PlayIntroMusic() { ¬ Загрузка музыки intro из папки Resources.

PlayMusic(Resources.Load("Music/"+introBGMusic) as AudioClip);

}

public void PlayLevelMusic() { ¬ Загрузка основной музыки из папки Resources.

PlayMusic(Resources.Load("Music/"+levelBGMusic) as AudioClip);

}

private void PlayMusic(AudioClip clip) { ¬ Воспроизведение музыки при помощи параметра AudioSource.clip. music1Source.clip = clip;

music1Source.Play();

}

public void StopMusic() { music1Source.Stop();

}

...

Как обычно, при выборе игрового диспетчера на панели Inspector можно увидеть новые сериализованные переменные. Перетащите на ячейку для источника аудио клип Music 1. Затем введите в две строковые переменные имена музыкальных файлов: introsynth и loop.

Остальная часть нового кода вызывает команды загрузки и воспроизведения музыки (или в последнем добавленном методе — остановки музыки). Команда Resources. Load() загружает именованный ресурс из папки Resources (учитывая, что нужные файлы расположены во вложенной папке Music). Эта команда возвращает обобщенный объект, но его можно преобразовать к конкретному типу (в данном случае — к типу AudioClip), воспользовавшись ключевым словом as.

Затем загруженный аудиоклип передается в метод PlayMusic(), который настраивает клип в компоненте AudioSource и вызывает метод Play(). Как я уже объяснял, звуковые эффекты лучше воспроизводятся методом PlayOneShot(), но установка клипа в компоненте AudioSource является более надежным подходом, позволяющим кроме всего прочего на время или совсем останавливать воспроизведение музыки.

260      Глава 10. Звуковые эффекты и музыка

Шаг 4. Добавление в UI элементов управления музыкой

Чтобы новые методы воспроизведения музыки выполняли какие-либо действия, их нужно откуда-то вызвать. Добавим к нашему UI дополнительные кнопки, щелчки на которых позволят включать разную музыку. Сейчас я опять перечислю этапы этого процесса с краткими пояснениями (подробности вы сможете найти в главе 6):

1.Измените ширину всплывающего окна на 350 (чтобы на нем поместились дополнительные кнопки).

2.Создайте новую кнопку и сделайте ее дочерним объектом по отношению к всплывающему окну.

3.Ширину кнопки сделайте равной 100 и поместите ее в точку с координатами 0, –20.

4.Раскройте иерархический список кнопки, выделите текстовую метку и поменяйте текст на Level Music.

5.Повторите эту последовательность еще два раза, чтобы создать две дополнительные кнопки.

6.Одну из них поместите в точку с координатами –105, –20, вторую — в точку с координатами 105, –20 (чтобы она появилась с другой стороны).

7.Текстовую метку первой кнопки поменяйте на Intro Music, второй — на No Music.

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

Листинг 10.10. Добавление элементов управления музыкой в сценарий SettingsPopup

...

public void OnPlayMusic(int selector) { ¬ Этот метод получает от кнопки численный параметр.

Managers.Audio.PlaySound(sound);

switch (selector) { ¬ Вызываем для каждой кнопки свою музыкальную функцию в диспетчере AudioManager. case 1:

Managers.Audio.PlayIntroMusic();

break; case 2:

Managers.Audio.PlayLevelMusic();

break;

default:

Managers.Audio.StopMusic();

break;

}

}

...

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

При помощи стандартной процедуры свяжем кнопку с этим кодом: добавьте элемент в список OnClick на панели Inspector, перетащите всплывающее окно на ячейку объекта