В какой-то момент каждый разработчик игры задумывается… а почему так тихо?
Если ваша игра не построена вокруг звукового сопровождения, как, например, Osu!, Guitar Hero или Hotline Miami, то вы вполне можете оказаться в ситуации, когда ваши игра уже почти готова, и тут вы понимаете: “Что-то не так”. Через пару минут размышлений оказывается что в игре нет звука =) Многие редко задумываются о такой важной части игры, и не удивительно, что могут вспомнить о ней в самый последний момент. Так что давайте поговорим немного о звуке.
Звук в Unity
Звуковые ассеты в Unity называются AudioClip, а их воспроизведение крутится вокруг двух компонентов AudioListener и AudioSource. AudioListener - это компонент, который ведёт себя как микрофон, он улавливает все звуки на сцене и проигрывает их через динамик. AudioSource - отвечает за проигрывание звука на сцене.
Соответственно, для того чтобы в игре был звук, необходимо добавить в какой-либо объект на сцене, компонент AudioListener, и обычно таким объектом становится камера. Нужно заметить, что нельзя добавлять больше одного листенера. А также необходимо добавить для всех воспроизводящих звук объектов компоненты AudioSource.
Можно разделить работу со звуком на три группы:
Фоновая музыка - её добавление мы рассмотрим в этой статьи
Звуки UI - приемлемым подходом будет добавление в необходимые UI элементы компонентов AudioSource, а их проигрывание привязать к UI эвентам этих элементов
Звуки в окружающем пространстве - эта группа несколько сложнее UI элементов, т.к. требует дополнительных механизмов накладывания звуков на динамические объекты, т.к. весь диапазон возможных звуков может быть довольно большим и их перечисление заранее довольно проблематичным. Работа с этой группой требует отдельного механизма и отдельной статьи =)
Задача
Добавить механизм проигрывания фоновой музыки. Несколько треков должны проигрываться друг за другом, с возможным добавлением задержки между ними. Предусмотреть возможность заглушения звука (допустим, для проигрывания рекламы).
Реализация
В качестве основы будет использован синглетон отвечающий за работу с фоновой музыкой. Больше о синглетонах вы можете прочитать в нашей предыдущей статье.
Для заглушения звука воспользуемся переменной, которая будет отслеживать количество эвентов для заглушения и возврата звуков.
usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;publicclassKhtMusicManager:KhtSingleton<KhtMusicManager>{// Задержка между треками
publicintnewTrackDelay=0;// Список треков
publicList<AudioClip>musicAudioClips=newList<AudioClip>();// Источник для проигрывания музыки
privateAudioSource_musicAudioSource=null;// Используется для отслеживания заглушения музыки
privateint_muted=0;protectedoverridevoidAwake(){// Настраиваем синглетон
base.Awake();DontDestroyOnLoad(gameObject);// Добавляем компонент для проигрывания музыки
_musicAudioSource=gameObject.AddComponent<AudioSource>();}// Start is called before the first frame update
voidStart(){// Запускаем проигрывание музыки
StartCoroutine(PlayBackgroudMusic());}// Заглушаем музыку
publicstaticvoidMute(){// Проверки для синглетона
if(ReferenceEquals(Instance,null)){return;}// Если звук не заглушён
if(Instance._muted==0){Instance._musicAudioSource.mute=true;}Instance._muted++;}// Возврат звука
publicstaticvoidTurnOn(){// Проверка на синглетон и запрет на отрицательный счётчик
if(ReferenceEquals(Instance,null)||Instance._muted==0){return;}// Включаем звук
Instance._muted--;if(Instance._muted==0){Instance._musicAudioSource.mute=false;}}// Запуск следующего трека
IEnumeratorPlayBackgroudMusic(){// Текущий индекс трека
intmusicIndex=0;// Проигрываем музыку, если она есть
while(musicAudioClips.Count>0){// Время для запуска следующего трека + задержка
floatwaitTime=musicAudioClips[musicIndex].length+newTrackDelay;// Проигрываем мелодию один раз
_musicAudioSource.PlayOneShot(musicAudioClips[musicIndex]);// Работа с текущим индексом трека
musicIndex++;if(musicIndex>=musicAudioClips.Count){musicIndex=0;}// Задержка для включения следующего трека
yieldreturnnewWaitForSeconds(waitTime);}}}
Заключение
Приведённая реализация демонстрирует довольно низкий порог входа в работу со звуком в Unity. На базовом уровне система довольно проста, однако, при необходимости, можно использовать более продвинутые компоненты по смешиванию звуков и наложению эффектов(например, изменение звука двигателя при въезде в тоннель), также распространено использование сторонних библиотек. Возвращаясь к нашей реализации, можно выделить функционал, который хотелось бы добавить: возможность запуска трека по id, остановку и перезапуск, рандомизацию и хоть каждый такой запрос не является чем-то сложным, всё вместе это выходит за рамки статьи для начального ознакомления, так что оставим это на будущее. Пока! =)