Unity에서는 Snapshot을 사용해
오디오 믹서 에셋의 상태(State)를
저장하고 불러올 수 있습니다.
이 Audio Mixer의 Master Mixer에는
두 개의 스냅샷이 생성되어 있는데,
이 경우에는 Unpaused와 Paused입니다.
Unpaused에는 레벨들이 설정되어 있고,
Cutoff freq의 차단 주파수도
설정되어 있습니다.
이 경우는 22000hz이죠.
Paused 스냅샷을 클릭하면
Cutoff freq를
365hz로 새로 지정해 둔 것이 보입니다.
이렇게 되어 있으면
Master Mixer의 Music 그룹에서 실행되는
음악 트랙의 높은 주파수를 감쇠하게 됩니다.
Esc 키를 누르면
음악 트랙이 저역 필터링될 겁니다.
그럼 한 번 확인해 보겠습니다.
Esc를 누르면 음악 트랙이
저역 필터링되고, 다시 누르면 (원래대로 돌아옵니다).
새로운 Snapshot을 생성하려면
Snapshot 영역의 + 버튼을 클릭합니다.
이제 Unpaused의 사본을 만들었으니
원하는 값을 설정할 수 있습니다. 그런 다음에
스냅샷 이름을 클릭하여
그 값들을 에디터에서 소환할 수 있습니다.
런타임에서 스냅샷 값을 불러오려면
TransitionTo 함수를 사용합니다.
TransitionTo는 초 단위의 float 변수를 사용하며,
한 스냅샷과 다른 스냅샷 사이를
보간할 수 있습니다.
TransitionTo는
현재 트랜지션하려고 하는
Audio Mixer 스냅샷에서 호출합니다.
이 프로젝트에서는
MenuCanvas라는 게임 오브젝트가 있습니다.
MenuCanvas에는
PauseManager라는 스크립트가 붙어 있습니다.
Monodevelop에서 PauseManager를 살펴보겠습니다.
PauseManager에는
네임스페이스 선언 using UnityEngine.UI와
using UnityEngine.Audio가 추가되었습니다.
또한
현재 Unity 에디터를 사용하고 있는지 점검하고,
만일 그렇다면
UnityEditor 네임스페이스를 포함시킬 것입니다.
클래스 안에서는 두 개의
AudioMixerSnapshot형 public 변수 paused
와 unpaused를 선언했습니다.
또한 Canvas형 변수
canvas를 선언했습니다.
Start 함수에서는 GetComponent를 사용해
레퍼런스를 canvas 컴포넌트에 연결합니다.
Update 함수에서는 Esc 키가 눌러졌는지
확인합니다.
Esc 키가 눌러졌으면
canvas의 활성화 상태를
만일 Disabled이면 Enabled로,
Enabled이면 Disabled로 변경합니다.
또한 Pause 함수를 호출합니다.
Pause에서는
Time.timeScale이
0인지 확인합니다.
만일 0이 아니라면 0으로 설정하고,
0이라면 1이 되게 합니다.
다음으로는 Lowpass 함수를 호출합니다.
Lowpass 함수도 역시
Time.timeScale이 0과 같은지 확인합니다.
0이면 TransitionTo 함수를
Paused 스냅샷에서 호출합니다.
부동소수점 파라미터
timeToReach를 파싱할 텐데,
이 경우에는 0.01초입니다.
Time.timeScale이 0이 아니면
TransitionTo 함수를
Unpaused 스냅샷에서 호출하고,
이번에도 똑같이
0.01초 파라미터를
트랜지션 진행 시간이 되도록 파싱합니다.
public 함수 Quit으로
UnityEditor를 사용하는지 아닌지를 확인하고,
만일 사용한다면
EditorApplication.isPlaying을 false로 지정합니다.
이는 씬의 플레이를 중지하게 된다는 의미입니다.
만약, 에디터를 사용하지 않는다면
즉, 이것이 게임의 빌드이면
Application.Quit을 호출하는데, 이것은
애플리케이션을 종료하고 바탕화면으로 나간다는 의미입니다.
Unity 에디터에서는 Paused와
Unpaused 스냅샷이
Audio Mixer 스냅샷에 할당되어 있습니다.
여기 Master Mixer에서 생성한 스냅샷이죠.
이것을 변경하고 싶으면
Asset Picker를 이용해 그렇게 할 수 있습니다.
스냅샷 간에 트랜지션이 일어날 때
기본 보간 커브는 직선입니다.
이것을 변경하려면 파라미터를 선택하면 되는데,
파라미터를 오른쪽 버튼 클릭하고
오버라이드 트랜지션 유형 중에 하나를 선택하세요.
Smoothstep Snapshot 트랜지션 유형을 선택하면
S자 트랜지션 커브를 제공하고,
Squared는 포물선 커브,
SquareRoot은 제곱근 커브를 제공합니다.
BrickwallStart는 트랜지션 시작 시에
보관된 값으로
즉시 트랜지션하고,
BrickwallEnd는 트랜지션이 시간이 지날 때까지
기다렸다가 보관된 값으로
급격한 트랜지션을 진행합니다.
TransitionTo를 사용하는 것 외에도
여러 스냅샷을
보간한 블렌드로
트랜지션하는 방법도 있는데,
이때는 TransitionToSnapshots 함수를 사용합니다.
TransitionToSnapshots 함수는 세 개의 파라미터를 가집니다.
첫 번째는 Audio Mixer 스냅샷의 배열을 이용해
어떤 스냅샷을 가지고 블렌드를
생성할 것인지 선택할 수 있습니다.
두 번째 파라미터는 부동소수점형 배열로서,
결과로 얻은 블렌드에서 각 요소의 가중치(weight)를
정할 수 있습니다.
세 번째 파라미터는 초 단위의 부동소수점형 변수인데,
새로운 블렌드에 도달하는 데 걸리는
시간을 지정합니다.
TransitionToSnapshots은
스냅샷을 포함하는 Audio Mixer, 즉
지금 트랜지션을 진행하고 있는 믹서에서 호출합니다.
여기 세 개의 큐브 트리거가 셋업되어 있습니다.
플레이어가 이들 중 하나와 부딪치면
두 스냅샷의 블렌드로
트랜지션할 것입니다.
각 스냅샷들은
Sound Effects 서브 믹서에서 설정되었습니다.
Sound Effects 서브 믹서는
Master Mixer의 Sound Effects 그룹에서 실행됩니다.
이 예제에서는 음악을 껐습니다.
Sound Effects 믹서의 Gunshots 그룹에
Send 효과를 추가했습니다.
이 효과는 Add에서 Send를 선택하면 됩니다
이 효과의 역할은 Gunshots 시그널의 사본을
Reverb Return에 추가해 놓은
Receive 효과로 보내는 것입니다.
Receive 효과는 이 시그널을
SFX Reverb 효과로 보내고, 그 결과 총성은 마치
소리가 울리는 공간에서 처럼 들릴 것입니다.
두 개의 스냅샷을 설정하였습니다.
하나는 아무 리버브가 없도록(No Reverb)
총성 Send 효과의 Send 레벨이
완전히 내려진 경우이고,
다음은 반향이 크게 걸리도록(Heavy Reverb)
끝까지 최대로 올린 경우입니다.
어떻게 들리는지 들어보도록 하죠.
Edit In Play Mode를 눌러놓고,
클릭하면 반향이 전혀 들리지 않습니다.(No Reverb)
Heavy Reverb를 선택합니다.
이 경우에는 의도적으로 아주 강하고 비현실적인
리버브를 넣었기 때문에 반향이 확실히 들릴 겁니다.
이렇게 세 개의
투명한 큐브 ReverbTrigger 1, 2 그리고 3을 만들어 보았습니다.
각 Reverb Trigger는 ReverbTrigger 스크립트의
사본을 가지고 있습니다.
ReverbTrigger는 아주 간단한 스크립트로
ReverbCtrl 스크립트를 위한
public 변수 한 개와
정수형 변수 triggerNr가 들어 있습니다.
플레이어가
이 스크립트가 붙은 트리거와 충돌하면
ReverbCtrl의 BlendSnapshot 함수를 호출할 것입니다.
이건 정수 트리거 번호를 가질 테고요.
Unity에서는 Reverb Ctrl 변수를
할당해 놓았는데,
그 스크립트가 연결되어 있는
AudioMixerControl 오브젝트를 끌어다 놓으면 됩니다.
또한 고유한 Trigger Nr를
트리거 오브젝트에 각각 할당했습니다.
AudioMixerControl 게임 오브젝트는
ReverbCtrl 스크립트를 가집니다.
ReverbCtrl 스크립트에 들어가면
네임스페이스에 using UnityEngine.Audio를 선언해 놓았습니다.
이렇게 하면
AudioMixer, AudioMixerSnapshot 클래스 같은
UnityEngine.Audio의 멤버를 사용할 수 있습니다.
AudioMixer형 public 변수
mixer, 그리고
AudioMixerSnapshot의 배열
snapshots를 선언해 놓았습니다.
또한 public 부동소수점형 배열
weights를 선언했는데, 이것을 사용해
스냅샷 상태들 사이를 블렌드할 때
각 스냅샷의 가중치를 지정할 것입니다.
public 함수 BlendSnapshot이 있는데,
이것은 정수형 TriggerNr를 파라미터로 가집니다.
플레이어가 콜라이더와 충돌할 때
ReverbTrigger 스크립트에서 가지게되는 정수입니다.
다음으로는 switch 문이 있는데,
TriggerNr를 가지고
어느 콜라이더와 충돌하는지 선택합니다.
case 1, case 2, case 3이 있죠.
각 케이스에서는
weights 배열의 가중치를 지정할 겁니다.
각 스냅샷이 블렌드에 기여하는
퍼센티지를 정해주는 거죠.
case 1은 플레이어가 제일 오른쪽의
빨간색 트리거 콜라이더를 트리거하면 선택됩니다.
weights 배열의 가중치는
1.0과 0으로 지정할 것입니다.
이것은 결과로 얻는 스냅샷
블렌드가
mixer.TransitionToSnapshots 함수를 호출하면
생성되는 블렌드가
스냅샷 배열의 0에서는 스냅샷 100%,
스냅샷 배열의 1에서는 스냅샷 0%인 블렌드가 된다는 뜻입니다.
case 3에서는 그 반대가 됩니다.
이 경우에는 No Reverb 스냅샷 0%,
Heavy Reverb 스냅샷 100%가 되겠죠.
하지만 case 2에서는
흥미로운 변화가 있고
스냅샷으로의 트랜지션이 아주 유용해집니다.
여기에서 세 번째 리버브 상태가 만들어집니다.
No Reverb 스냅샷의 25%와
Heavy Reverb 스냅샷의
75% 블렌드로 트랜지션하는 거죠.
따라서
기존의 스냅샷 두 개의 블렌드로
트랜지션해서 세 번째 리버브 상태를 생성한 겁니다.
Unity에서 Reverb Ctrl 스크립트의
변수들을 할당해 놓았습니다.
Sound Effects Mixer 에셋을
Mixer 변수 슬롯으로 끌어다 놓았죠.
또한 스냅샷들도
리스트에서 클릭하고 선택해서 할당했습니다.
여기 보면 No Reverb 스냅샷이 있고,
여기에는 Heavy Reverb 스냅샷이 있습니다.
또한 Weights 배열의 Size는
2로 지정했습니다.
그러면 Snapshots 배열의 Size와
일치합니다. 따라서 이 요소들의 리스트가
정렬되겠죠.
여기서 값을 초기화하지 않은 것은
런타임에 스크립트에 의해 지정될 것이기 때문입니다.
이걸 시험해 볼 때는
Gunshots 트랙의 Reverb Return 레벨과
캐릭터가 각기 다른 트리거를 통과할 때
어떻게 달라지는지 주의해서 보도록 하세요.
그럼 한 번 시험해 보겠습니다.
여기서 한 일이 뭔가 하면
두 개의 스냅샷 No Reverb와 Heavy Reverb를 사용해서
보라색 콜라이더로 보여지는
이 세 번째 블렌드 스냅샷을 만들어낸 것입니다.
그리고 여기서는 리버브를 보이도록 선택했지만
이 기술은 모든 종류의 오디오 상태에 적용할 수 있고,
스냅샷에 저장할 수 있는
어떤 유형의 믹서 상태도
이와 똑같은 방법을 이용해
블렌드하고 불러올 수 있습니다.