- PVSM.RU - https://www.pvsm.ru -
Вместо предисловия.
Микширование в Unity 5.0 через AudioMixer это, наверное, очень круто.
Но мне нужно было решение здесь и сейчас (на тот момент — в 4.5.2f1).
Задач было три:
Программист из меня, мягко говоря, пока что никакой, поэтому большинство задач я решаю с помощью гугла и изучения документации Юнити.
Итак, начнём по порядку.
Создаём новый js скрипт, люблю дурацкие названия — назову его FadeOutAndDestrTimerWhenNextLvlLoad
Первое, что нам нужно — чтобы объект «звук» не уничтожился при переходе на следующий уровень.
Зачем? Затем, чтобы сделать ему плавное затухание и затем удалить.
Лезем читать документацию.
Ага, нам нужна строчка:
DontDestroyOnLoad (transform.gameObject);
Всё, этого достаточно.
Исходя из наших требований, обдумываем три «изменябельных» переменных:
Конвевертируем мысли в строчки:
var fadeTime = 0;
var levelToExecute = 0;
var DestroyTime = 0;
Ага, значит далее скрипт будет состоять из двух функций — «таймер удаления» и «механизм затухания».
Начнем с «таймера удаления».
Тут все элементарно:
function OnLevelWasLoaded (level : int) {
if (level == (levelToExecute))
{
Destroy (gameObject, DestroyTime);
//Destroy (gameObject, 20); //- можно и так, конечно.
}
}
Если номер загруженного уровня будет соответствовать указанному нами в окошке «levelToExecute»,
то запускается «таймер удаления» — от момента загрузки уровня до времени, указанного нами в окошке DestroyTime.
Хм, а почему бы нам не добавить сразу и запуск (ещё не написанной) функции «механизм затухания» сюда же? Можно.
function OnLevelWasLoaded (level : int) {
if (level == (levelToExecute))
{
FadeAudio(fadeTime, Fade.Out);
//продолжительность затухания, тип фейда - затухание(а не усиление)
Destroy (gameObject, DestroyTime);
}
}
Теперь осталось написать функцию «механизм затухания», допустим такой метод:
function FadeAudio (timer : float, fadeType : Fade) {
var start = fadeType == Fade.In? 0.0 : 1.0; //на старте (указанного нового уровня) произойдёт усиление звука из 0 до 1
var end = fadeType == Fade.In? 1.0 : 0.0; //в конце произойдёт угасание из 1 в 0
var i = 0.0; //переменное значение (громкости)
var step = 1.0/timer; //шаг ("плавного" изменения громкости) равен единице громкости / таймер
while (i <= 1.0) { // до тех пор, ПОКА "0" (громкость) равна или меньше "1" исполнять ↓ ,
//вплоть до получения значения "0"
i += step * Time.deltaTime;
audio.volume = Mathf.Lerp(start, end, i);
// Mathf.Lerp - находим промежуточные значения громкости соответственно имеющимся start, end, и значение "i"
//растягиваем во времени изменение звука
yield;
}
}
Вот, что у нас получилось:
Мы уже знаем почти все, что нужно для этой части.
Добавим чуть-чуть.
Что из себя представляет микширование/луп традиционным способом (как это понимаю дилетант я)?
Вот, например, скриншот из Adobe Audition.
Берём трек (0), делаем возрастание громкости вначале (1) и затухание в конце (2),
клонируем результат в начало (3) и в конец (4), со смещением до середины затуханий (5), обрезаем лишнее (6).
7 — Сохраняем результат в ogg (или в mp3).
Мы теряем немного материала в начале и в конце, обрезанные, хм… начало и конец «загрязняются» примесью друг друга.
Как-то так, можно, конечно и по-другому.
Например ,«срезать» полностью вначале или в конце, оставив эм… перекрестие затуханий в противоположном начале или в конце.
Но это «съест» ещё больше материала.
Почему я делаю это программно?
Создаём новый js скрипт, я назову его StartFadeIn_CloneTimer_FadeOut_DestrTimer
Обратите внимание — название не просто дурацкое, в нем указана последовательность исполнения функций, мне так удобно.
Кстати, изначально я написал п.1 и п.2-3 в один скрипт, но оказалось удобнее отключать «кусочек» при потребности.
Можете их объединить, чуть подкорректировав.
Оглянемся назад, в начало статьи — какие требования предъявлены будущему скрипту?
Музыка, за ~N секунд до своего финала, должна начать плавно затухать и плавно переходить с усилением в собственное начало.
Что из этого выплывает?
Подумаем как это реализовать:
Конвертируем мысли в строчки, опять же, перечислим, что у нас здесь есть затухание и усиление, и создадим четыре переменных:
enum Fade {In, Out} // для объявления перечисления - наших "усиление" и "затухание"
var prefab : Transform; //выбор объекта "звук"
var DestroyTime: float = 1; //время (задержка) до удаления
var CloneTime: float = 1; //время (задержка) до клонирования
var fadeTime: float = 1; //продолжительность угасания/усиления
Добавим функцию «Старт»:
function Start(){
Spawn();
//↑запуск функции "Спавн" (клонирование)
FadeAudio(fadeTime, Fade.In );
//↑запуск функции "Фейд", включая указанную в переменной продолжительность и тип фейда - усиление
Destroy ((prefab as Transform).gameObject, DestroyTime);
//↑удаление выбранного объекта звук по истечению времени, указанного в DestroyTime
}
Теперь по порядку, добавим перечисленные выше функции. Клонирование:
function Spawn(){
while( true ){
yield WaitForSeconds(CloneTime); //задержка до исполнения, указана в переменной CloneTime
for (var i : int = 0;i < 1; i++)
{ Instantiate (prefab, Vector3(i * 2.0, 0, 0), Quaternion.identity); } //клонирование выбранного объекта "звук"
FadeAudio(fadeTime, Fade.Out);
}
}
Функция «Фейд» у нас уже есть — копипастим её из первой части статьи:
function FadeAudio (timer : float, fadeType : Fade) {
var start = fadeType == Fade.In? 0.0 : 1.0;
var end = fadeType == Fade.In? 1.0 : 0.0;
var i = 0.0;
var step = 1.0/timer;
while (i <= 1.0) {
i += step * Time.deltaTime;
audio.volume = Mathf.Lerp(start, end, i);
yield;
Debug.Log (audio.volume);
//проверка срабатывания фейда логируется в консоль - можно удалить/отключить
}
}
Вот, что у нас получилось:
Смотрим длину нашего трека, конвертируем её в секунды = DestroyTime
Если лень посчитать — можно использовать онлайн-конвертер минут (гугл в помощь) + добавить остаток секунд.
Отнимаем продолжительность фейда = CloneTime
Вписываем полученные значения в окошки.
В перфаб добавляем нужный трек.
Фейд по вкусу.
Вы должны проследить за тем, чтобы задержка до клонирования/продолжительность фейда/время удаления
не конфликтовали с временными параметрами скрипта из первой части статьи —
иначе при переходе на следующий уровень трек может не успеть самоудалиться и начнёт создавать множество своих копий.
…
И напоследок, если вам интересно, для чего это делается:
steamcommunity.com/sharedfiles/filedetails/?id=252305314 [1]
Автор: ironwool
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/80149
Ссылки в тексте:
[1] steamcommunity.com/sharedfiles/filedetails/?id=252305314: http://steamcommunity.com/sharedfiles/filedetails/?id=252305314
[2] Источник: http://habrahabr.ru/post/248371/
Нажмите здесь для печати.