Воспроизведение звука в Unity и добавление музыки в приложение
Процесс добавления звуков в Unity одинаков для 2D и 3D. Разница будет лишь при настройк е звуков и при присваивании их объектам.
В Unity есть такое понятие как AudioSource — это источник звука. Именно он воспроизводит звуки в игровых сценах. Но воспроизводит он не просто звуки, а Audio Clip, которые нужно добавить в игру.
«Аудиоклип» может являться как 3D , так и 2D клипом, трансформировать его между этими форматами можно при помощи свойства PanLevel и использовать в соответствующих играх. По сути «аудиоклип» — это люб ые звуки или мелоди и , котор ые нужно воспроизводить в игре, «аудиоисточник» — это, своего рода, контроллер, который воспроизводит нужный «аудиоклип» в нужном месте, изменяя при необходимости его свойства.
Как создать источник воспроизведения звука в Unity
- Нужно импортировать звуки или мелодии в свой игровой проект на Unity в папку Assets. При этом не забывайте об авторских правах импортируемых мелодий.
- Потом нужно пройти по следующему пути в меню: GameObject-CreateEmp t y.
- Выделите созданный GameObject, потом в меню пройдите по следующему пути: Component-Audio-AudioSource.
- Задайте «аудиоклип» к выбранному компоненту «аудиоисточника».
Как добавить музыку в Unity
- приобрести ее за деньги с гарантией, что она уникальна;
- заказать у знакомых музыкантов звуковое сопровождение вашей игры;
- воспользоваться бесплатными аудиобанками;
- запишите мелодию самостоятельно.
- найти подходящую песню на специальных ресурсах, где она распространяется с открытой лицензией;
- поискать музыкантов-любителей, которые не прочь запечатлеть свое творчество в вашей игре;
- либо , опять же, все можно сделать самостоятельно.
Заключение
- Изначально сохраняйте собственные звуки в несжатом формате, а оптимизацию потом делайте непосредственно в Unity.
- Если звук искажается при движении персонажа, то обратите внимание на параметр Doppler Level в AudioSource и от регулируйте его до нужного состояния звука или уберите его совсем «в ноль», чтобы звук вообще не искажался.
- Если нужна фоновая музыка, то лучше ее обыгрывать на ближайшем к AudioListener объекте.
- Чтобы фоновая музыка проигрывалась без проблем, то снимите галочку с «3D Sound» в самом аудиофайле.
- При добавлении звуков обращайте внимание на галочку «3D Sound» — она нужна, когда наша игра в 3D ; если ваша игра в 2D, тогда снимите ее.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Как добавить музыку в игру unity
В какой-то момент каждый разработчик игры задумывается… а почему так тихо?
Если ваша игра не построена вокруг звукового сопровождения, как, например, Osu!, Guitar Hero или Hotline Miami, то вы вполне можете оказаться в ситуации, когда ваши игра уже почти готова, и тут вы понимаете: “Что-то не так”. Через пару минут размышлений оказывается что в игре нет звука =) Многие редко задумываются о такой важной части игры, и не удивительно, что могут вспомнить о ней в самый последний момент. Так что давайте поговорим немного о звуке.
Звук в Unity
Звуковые ассеты в Unity называются AudioClip , а их воспроизведение крутится вокруг двух компонентов AudioListener и AudioSource . AudioListener — это компонент, который ведёт себя как микрофон, он улавливает все звуки на сцене и проигрывает их через динамик. AudioSource — отвечает за проигрывание звука на сцене.
Соответственно, для того чтобы в игре был звук, необходимо добавить в какой-либо объект на сцене, компонент AudioListener , и обычно таким объектом становится камера. Нужно заметить, что нельзя добавлять больше одного листенера. А также необходимо добавить для всех воспроизводящих звук объектов компоненты AudioSource .
Можно разделить работу со звуком на три группы:
- Фоновая музыка — её добавление мы рассмотрим в этой статьи
- Звуки UI — приемлемым подходом будет добавление в необходимые UI элементы компонентов AudioSource , а их проигрывание привязать к UI эвентам этих элементов
- Звуки в окружающем пространстве — эта группа несколько сложнее UI элементов, т.к. требует дополнительных механизмов накладывания звуков на динамические объекты, т.к. весь диапазон возможных звуков может быть довольно большим и их перечисление заранее довольно проблематичным. Работа с этой группой требует отдельного механизма и отдельной статьи =)
Задача
Добавить механизм проигрывания фоновой музыки. Несколько треков должны проигрываться друг за другом, с возможным добавлением задержки между ними. Предусмотреть возможность заглушения звука (допустим, для проигрывания рекламы).
Реализация
В качестве основы будет использован синглетон отвечающий за работу с фоновой музыкой. Больше о синглетонах вы можете прочитать в нашей предыдущей статье.
Для заглушения звука воспользуемся переменной, которая будет отслеживать количество эвентов для заглушения и возврата звуков.
KhtMusicManager.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
using System.Collections; using System.Collections.Generic; using UnityEngine; public class KhtMusicManager : KhtSingletonKhtMusicManager> // Задержка между треками public int newTrackDelay = 0; // Список треков public ListAudioClip> musicAudioClips = new ListAudioClip>(); // Источник для проигрывания музыки private AudioSource _musicAudioSource = null; // Используется для отслеживания заглушения музыки private int _muted = 0; protected override void Awake() // Настраиваем синглетон base.Awake(); DontDestroyOnLoad(gameObject); // Добавляем компонент для проигрывания музыки _musicAudioSource = gameObject.AddComponentAudioSource>(); > // Start is called before the first frame update void Start() // Запускаем проигрывание музыки StartCoroutine(PlayBackgroudMusic()); > // Заглушаем музыку public static void Mute() // Проверки для синглетона if (ReferenceEquals(Instance, null)) return; > // Если звук не заглушён if (Instance._muted == 0) Instance._musicAudioSource.mute = true; > Instance._muted++; > // Возврат звука public static void TurnOn() // Проверка на синглетон и запрет на отрицательный счётчик if (ReferenceEquals(Instance, null) || Instance._muted == 0) return; > // Включаем звук Instance._muted--; if (Instance._muted == 0) Instance._musicAudioSource.mute = false; > > // Запуск следующего трека IEnumerator PlayBackgroudMusic() // Текущий индекс трека int musicIndex = 0; // Проигрываем музыку, если она есть while (musicAudioClips.Count > 0) // Время для запуска следующего трека + задержка float waitTime = musicAudioClips[musicIndex].length + newTrackDelay; // Проигрываем мелодию один раз _musicAudioSource.PlayOneShot(musicAudioClips[musicIndex]); // Работа с текущим индексом трека musicIndex++; if (musicIndex >= musicAudioClips.Count) musicIndex = 0; > // Задержка для включения следующего трека yield return new WaitForSeconds(waitTime); > > >
Заключение
Приведённая реализация демонстрирует довольно низкий порог входа в работу со звуком в Unity. На базовом уровне система довольно проста, однако, при необходимости, можно использовать более продвинутые компоненты по смешиванию звуков и наложению эффектов(например, изменение звука двигателя при въезде в тоннель), также распространено использование сторонних библиотек. Возвращаясь к нашей реализации, можно выделить функционал, который хотелось бы добавить: возможность запуска трека по id, остановку и перезапуск, рандомизацию и хоть каждый такой запрос не является чем-то сложным, всё вместе это выходит за рамки статьи для начального ознакомления, так что оставим это на будущее. Пока! =)
Audio Source
Audio Source (источник звука) воспроизводит Audio Clip в сцене. Если Audio Clip является 3D клипом, источник проигрывается в заданном положении в пространстве и будет приглушаться в зависимости от расстояния. Аудио может быть распределено по колонкам (например, из стерео в 7.1) с помощью свойства Spread и трансформироваться между 3D и 2D с помощью свойства PanLevel. Можно контролировать зависимость этих эффектов от расстояния с помощью кривых затухания. Также если слушатель находится в одной или нескольких зонах реверберации, то к источнику применяются реверберации (только для Unity Pro). Для обогащения аудио ряда, к источнику можно применять отдельные аудио фильтры. См. справку по аудио эффектам для дополнительной информации.
Свойства
Свойство: | Функция: |
---|---|
Audio Clip | Ссылка на аудио клип для проигрывания этим источником. |
Output | By default, the clip is output directly to the Audio Listener in the Scene. Use this property to output the clip to an Audio Mixer instead. |
Mute | Если включено, звук всё ещё будет проигрываться, но не будет слышен. |
Bypass Effects | Для быстрого пропуска всех эффектов, применённых к источнику звука. Простой путь включения/отключения всех эффектов. |
Bypass Listener Effects | Для быстрого включения/отключения всех эффектов, применённых к слушателю. |
Bypass Reverb Zones | Для быстрого включения/отключения всех зон реверберации. |
Play On Awake | Если включено, звук начнёт воспроизводиться сразу после загрузки сцены. Если отключено, вам потребуется запустить звук программно, с помощью метода Play(). |
Loop | Включите для бесконечного повтора Audio Clip’а после его окончания. |
Priority | Определяет приоритет данного источника звука среди всех остальных источников в сцене (0 = наиболее важный, 256 = наименее важный, 128 по умолчанию). Используйте 0 для музыки, чтобы избежать её случайного переключения. |
Volume | Насколько громок звук на расстоянии одной мировой единицы измерения (одного метра) от слушателя (Audio Listener’а). |
Pitch | Степень изменения высоты тона при замедлении/ускорении Audio Clip’а. Величина 1 означает нормальную скорость воспроизведения. |
Stereo Pan | Sets the position in the stereo field of 2D sounds. |
Spatial Blend | Устанавливает степень влияния 3D движка на источник звука. |
Reverb Zone Mix | Sets the amount of the output signal that gets routed to the reverb zones. The amount is linear in the (0 — 1) range, but allows for a 10 dB amplification in the (1 — 1.1) range which can be useful to achieve the effect of near-field and distant sounds. |
3D Sound Settings | Settings that are applied proportionally to the Spatial Blend parameter. |
Doppler Level | Определяет количество эффекта доплера, применяемого к данному источнику (при значении 0 эффект применяться не будет). |
Spread | Устанавливает угол распространения для 3d стерео или мультиканального звука в пространстве динамиков. |
Min Distance | Громкость звука будет максимальной, насколько это возможно, на протяжении MinDistance. Вне MinDistance она будет постепенно снижаться. Увеличьте MinDistance звука, чтобы сделать его “громче” в трёхмерном мире; снизьте, чтобы сделать звук “тише” в трёхмерном мире. |
Max Distance | Расстояние, на котором звук перестаёт затухать. За пределами этой точки его громкость останется на уровне, на котором она была бы на расстоянии MaxDistance единиц от слушателя и больше не будет затухать. |
Rolloff Mode | Как быстро звук угасает. Чем выше значение, там ближе должен быть слушатель к звуку прежде, чем его можно будет услышать (определяется по графику). |
— Logarithmic Rolloff | Громкость звука высока, когда вы близко к источнику, но при удалении от объекта она довольно быстро падает. |
— Linear Rolloff | Чем вы дальше от источника звука, тем хуже вы его слышите. |
— Custom Rolloff | Звук источника аудио ведёт себя соответственно графику затуханий. |
Типы спадания
Существует три типа спадания (Rolloff Mode): Logarithmic Rolloff (логарифмическое спадание), Linear Rolloff (линейное спадание) и Custom Rolloff (пользовательское спадание). Custom Rolloff настраивается с помощью кривой зависимости громкости от расстояния, как описано ниже. Если вы попытаетесь изменить кривую в то время, как у вас выбран тип Logarithmic или Linear, то он автоматически сменится на Custom Rolloff.
Функции расстояния
Существует несколько свойств аудио, которые могут меняться по функции расстояния между источником и слушателем звука.
Volume: Amplitude(0.0 — 1.0) over distance.
Spatial Blend: 2D (original channel mapping) to 3D (all channels downmixed to mono and attenuated according to distance and direction).
Spread: Angle (degrees 0.0 — 360.0) over distance.
Low-Pass (только если к источнику добавлен LowPassFilter): Частота отсекания (22000.0–10.0).
Reverb Zone: Amount of signal routed to the reverb zones. Note that the volume property and distance and directional attenuation are applied to the signal first and therefore affect both the direct and reverberated signals.
Вы можете напрямую менять кривые для изменения функций расстояния. Для дополнительной информации см. руководство по редактированию кривых.
Создание источников звука
Источники звука не производят никаких действий без назначенного Audio Clip’а. Клип представляет собой звуковой файл, который будет проигрываться. Источник выступает в роли контроллера, запускающего и останавливающего воспроизведение того клипа, при этом изменяя другие аудио свойства.
Для создания нового источника звука:
- Импортируйте ваши аудио файлы в Unity проект. Теперь они — аудио клипы.
- Вызовите пункт GameObject->Create Empty из строки меню.
- При выделенном, только что созданном GameObject’е, выберите пункт меню Component->Audio->Audio Source.
- In the Inspector, find the Audio Clip property on the Audio Source Component and assign a clip, either by dragging one from the Project Window or by clicking the small circle icon to the right of the Inspector property, then selecting a clip from the list.
Важно: Если вы хотите создать Audio Source только для одного Audio Clip’а, который находится в папке Assets вашего проекта, то вы можете просто перетащить клип в окно сцены — GameObject с компонентом Audio Source для вашего клипа будет создан автоматически. Перетаскивание клипа на существующий GameObject добавит на него клип вместе с новым Audio Source, если этого компонента там ещё нет. Если на объекте уже есть компонент Audio Source, тогда новый клип, который вы перетащили, заменит тот, который уже используется источником звука.
Воспроизведение и управление звуками в Unity 3D (Sound complete event, Play in edit mode)
К этой статье будет приложен небольшой, но полезный csharp скрипт, и показано как им пользоваться.
Поводом для написания скрипта стало то, что появилась необходимость в настройке и тестировании звуковых эффектов не запуская сцены проекта. А так же в отслеживании основных событий воспроизведения.
Скрипт работает одинаково как в PlayMode так и в EditMode, и позволяет:
1. Воспроизвести звук с необходимой задержкой и отследить начало воспроизведения.
2. Отследить окончание звука, в том числе каждый момент завершения зацикленного воспроизведения.
3. Отследить незапланированное окончание воспроизведения звука.
4. Использовать событие для отслеживания и изменения параметров в процессе воспроизведения.
Для воспроизведения звука используются статические методы:
public static SoundTrack PlaySound(AudioClip clip, float volume = 1, float pitch = 1, float loopTime = 0, float delayTime = 0); public static SoundTrack PlaySound(GameObject target, AudioClip clip, float volume = 1, float pitch = 1, float loopTime = 0, float delayTime = 0);
Эти методы возвращают экземпляр класса SoundTrack, к которому в последствии можно прикрепить необходимые события. Первый метод создаёт на сцене GameObject, второй добавляет указанному GameObject компоненты SoundTrack и AudioSource.
Параметры volume и pitch не нуждаются, наверное, в представлении.
loopTime – можно использовать для задания времени в секундах, которое будет длиться цикл воспроизведения. При значении 0 звук проиграется только один раз, при значении float.PositiveInfinity звук будет проигрываться бесконечно.
delayTime – это задержка перед воспроизведением звука в секундах.
Примечание:
По прошествии loopTime, первый метод удалит созданный для звука GameObject, второй метод удалит только созданные для звука компоненты.
Итак, самый простой пример кода для воспроизведения звука в игре.
public AudioClip testSound; void Start ()
И для воспроизведения звука в редакторе.
[MenuItem("MyMenu/TestSound #F1")] static void TestSound()< AudioClip[] clips=Resources.FindObjectsOfTypeAll(); if(clips==null||clips.Length==0) < Debug.LogError("No clips in the resources!"); return; >SoundTrack.PlaySound(clips[0]); >
Теперь можно попробовать разобраться с событиями. Думаю для наглядности лучше сразу взять пример для редактора, так как в режиме игры всё работает аналогично.
Данный пример запускается сочетанием клавиш SHIFT+F1, и показывает как использовать события.
using UnityEngine; using UnityEditor; using System.Collections; public class SoundTrackTest : Editor < [MenuItem("MyMenu/TestSound #F1")] static void TestSound()< clips=Resources.FindObjectsOfTypeAll(); Debug.Log("clips " + clips.Length); if(clips==null||clips.Length==0) < Debug.LogError("No clips in the resources!"); return; >rePlayCount = 0; StartNextSound (0); > static AudioClip[] clips; static int rePlayCount=0; static void StartNextSound(float timePosition)< SoundTrack track=SoundTrack.PlaySound(clips[Random.Range(0,clips.Length-1)]); rePlayCount++; // событие начала звука track.start_action += soundStartEvent; // событие срабатывает каждый кадр track.processing += soundProcessEvent; // это событие подходит только для зацикленного воспроизведения // оно срабатывает каждый раз, когда звук завершается track.complete_action += soundCompleteEvent; // событие срабатывает при далении звука track.destroy_action += soundDestroyEvent; if(timePosition>0) < // перематывает точку воспроизведения на определённый момент, в секундах track.setTimePosition (timePosition); >> static void soundStartEvent(SoundTrack track) < Debug.Log("Sound Start event!"); >static void soundProcessEvent(SoundTrack track) < track.volume = track.playing_time % 1f; >static void soundCompleteEvent(SoundTrack track, float offset) < Debug.Log("Sound Complete event! "+offset); >static void soundDestroyEvent(SoundTrack track, bool atEndOfSound, float offset) < Debug.Log("Sound Destroy event! "+offset); // проверяет было ли уничтожение инициировано из за окончания воспроизведения // atEndOfSound будет равен false в случае если воспроизведения было прервано по другим причинам // к примеру при удалении звука со сцены вручную и т.д. if(atEndOfSound)< // данный подход демонстрирует как можно плавно соединить несколько последовательных звуков // offset - это неизбежная задержка вызова события // можно её компенсировать используя track.setTimePosition для следующего звука // это сделано чтобы звуки в редакторе не воспроизводились бесконечно // так как если звук очень короткий, это будет весьма неприятный тест if(rePlayCount<4)< StartNextSound (offset); >> > >
Для того чтобы пример работал, этот скрипт надо положить в папку Editor, а так же иметь в ресурсах проекта хотя бы один звуковой файл. Если нужен тест в запущенном проекте, то можно просто из функции TestSound перенести код в функцию Start, и если нужно, то сделать все свойства и метода нестатическими.
void Start()< clips=Resources.FindObjectsOfTypeAll(); Debug.Log("clips " + clips.Length); if(clips==null||clips.Length==0) < Debug.LogError("No clips in the resources!"); return; >rePlayCount = 0; StartNextSound (0); >
Это событие срабатывает непосредственно при начале воспроизведения звука.
track.start_action += soundStartEvent; // событие начала звука
Т.е. в случае, если delayTime > 0, оно сработает не при создании звука, а при старте воспроизведения.
Это событие может быть полезно в ряде случаев.
track.processing += soundProcessEvent; // событие срабатывает каждый кадр
К примеру можно музыке и эффектам задать разные события, и одной переменной регулировать громкость всей музыки в игре, а другой всех эффектов. А потом добавить и эффектам и музыке ещё одно событие, в котором уже регулировать скорость их воспроизведения, если в игре есть эффект Slow Motion.
В данном примере звук должен в течении каждой секунды менять громкость.
track.complete_action += soundCompleteEvent; // событие срабатывает каждый раз, когда звук завершается
Это событие может пригодиться в ситуации, когда loopTime превышает длину звукового файла, это значит, что звук будет проигрываться циклично. В этом случае событие будет срабатывать в тот момент, когда звук начинается заново. В остальных случаях вызов этого события не гарантируется.
track.destroy_action += soundDestroyEvent; // событие срабатывает при удалении звука
Это событие сработает в 2-х случаях. Первый случай, это когда воспроизведение звука завершено, по истечении loopTime или при одноразовом воспроизведении. Второй случай, это никак не связанное с логикой скрипта удаление звука со сцены (например вручную удалив объект из иерархии сцены). Отличить один случай от другого можно с помощью параметра atEndOfSound, если он равен false, то это как раз второй случай.
Во втором случае мы уже не будем иметь доступ к GameObject’у и компонентам звука.
Если к примеру необходимо последовательно проиграть несколько мелодий и создать ощущение непрерывного звучания, можно попробовать сделать это как показано в примере, в функции soundDestroyEvent.
- time_position — позиция воспроизведения аудиофайла, от 0 до длины файла;
- life_time — время с начала воспроизведения звука;
- playing_time — время затраченное на воспроизведения звука, не учитывает паузы;
- loop_time — время, которое звук будет проигрываться;
- delay_time — время задержки перед воспроизведением;
- startTime — момент начала воспроизведения звука;
- created_time — момент создания звука (startTime-delay_time).
Всё время расчитывается относительно Time.realtimeSinceStartup.
Здесь можно скачать сам скрипт и приведённый выше пример.
Если в примере не работает сочетание клавиш, можно найти пункт TestSound в меню.
Если Unity не находит звук в ресурсах, надо его просто выделить (посмотреть настройки аудиофайла).