Unity Audio Mixer 고급 활용
Unity Audio Mixer는 오디오 신호를 그룹으로 라우팅하고 이펙트를 적용하는 DAW 스타일의 믹싱 도구입니다. 배경음, 효과음, 대화를 별도 그룹으로 분리해 독립적으로 제어하고, 스냅샷으로 전투/메뉴/컷씬 전환 시 믹스를 부드럽게 바꿀 수 있습니다.
1. Mixer 그룹 구조 설계
섹션 제목: “1. Mixer 그룹 구조 설계”Master├── Music (BGM)│ └── Music_Ducked (전투 중 감쇄)├── SFX (효과음)│ ├── Footsteps│ ├── Weapons│ └── UI_SFX├── Voice (대화/VO)│ └── Voice_Radio (라디오 필터 적용)└── Ambient (환경음)2. 런타임 볼륨 제어
섹션 제목: “2. 런타임 볼륨 제어”using UnityEngine.Audio;
public class AudioManager : MonoBehaviour{ [SerializeField] private AudioMixer _mixer;
// PlayerPrefs와 연동한 볼륨 설정 public void SetMusicVolume(float normalizedVolume) { // AudioMixer는 dB 단위 (-80dB ~ 0dB) float dB = normalizedVolume > 0.001f ? Mathf.Log10(normalizedVolume) * 20f : -80f;
_mixer.SetFloat("MusicVolume", dB); PlayerPrefs.SetFloat("MusicVolume", normalizedVolume); }
public float GetMusicVolume() { _mixer.GetFloat("MusicVolume", out float dB); return Mathf.Pow(10f, dB / 20f); // dB → 선형 }
// 노출된 파라미터 이름 상수화 (오탈자 방지) private static class Params { public const string Music = "MusicVolume"; public const string SFX = "SFXVolume"; public const string Voice = "VoiceVolume"; public const string Ambient = "AmbientVolume"; }}3. 스냅샷 전환
섹션 제목: “3. 스냅샷 전환”public class AudioSnapshotController : MonoBehaviour{ [SerializeField] private AudioMixer _mixer; [SerializeField] private AudioMixerSnapshot _normalSnapshot; [SerializeField] private AudioMixerSnapshot _combatSnapshot; [SerializeField] private AudioMixerSnapshot _menuSnapshot; [SerializeField] private AudioMixerSnapshot _underwaterSnapshot;
public void TransitionToCombat(float transitionTime = 0.5f) { _combatSnapshot.TransitionTo(transitionTime); }
public void TransitionToNormal(float transitionTime = 1f) { _normalSnapshot.TransitionTo(transitionTime); }
// 여러 스냅샷 블렌딩 (물 속에 반쯤 잠긴 경우) public void SetUnderwaterBlend(float blend) { // blend: 0=Normal, 1=Underwater var snapshots = new[] { _normalSnapshot, _underwaterSnapshot }; var weights = new[] { 1f - blend, blend };
_mixer.TransitionToSnapshots(snapshots, weights, 0.1f); }}4. AudioSource를 믹서 그룹에 라우팅
섹션 제목: “4. AudioSource를 믹서 그룹에 라우팅”public class SoundEmitter : MonoBehaviour{ [SerializeField] private AudioMixerGroup _sfxGroup; [SerializeField] private AudioMixerGroup _voiceGroup;
private AudioSource _sfxSource; private AudioSource _voiceSource;
void Awake() { // SFX 소스 → SFX 그룹 _sfxSource = gameObject.AddComponent<AudioSource>(); _sfxSource.outputAudioMixerGroup = _sfxGroup; _sfxSource.spatialBlend = 1f; // 3D
// Voice 소스 → Voice 그룹 _voiceSource = gameObject.AddComponent<AudioSource>(); _voiceSource.outputAudioMixerGroup = _voiceGroup; _voiceSource.spatialBlend = 1f; }
public void PlaySFX(AudioClip clip, float volume = 1f) { _sfxSource.PlayOneShot(clip, volume); }
public void PlayVoice(AudioClip clip) { _voiceSource.clip = clip; _voiceSource.Play(); }}5. Send/Receive — 리버브 공유
섹션 제목: “5. Send/Receive — 리버브 공유”// Mixer 설정 (인스펙터):// SFX 그룹에 "Send" 이펙트 추가 → Reverb_Bus로 전송// Reverb_Bus 그룹에 "Receive" + "SFX Reverb" 이펙트 추가
// 런타임에서 리버브 양 조절public class ReverbController : MonoBehaviour{ [SerializeField] private AudioMixer _mixer;
public void SetReverbWet(float wet) { // 0 = 드라이, 1 = 완전 리버브 float sendLevel = Mathf.Lerp(-80f, 0f, wet); _mixer.SetFloat("SFX_ReverbSend", sendLevel); }
// 실내/실외 전환 public void EnterBuilding() => SetReverbWet(0.6f); public void ExitBuilding() => SetReverbWet(0.0f);}6. Duck Volume — 배경음 자동 감쇄
섹션 제목: “6. Duck Volume — 배경음 자동 감쇄”// Duck Volume 이펙트: Voice 그룹이 재생되면 Music 자동 감쇄// Mixer 설정:// Voice 그룹 → "Duck Volume" 이펙트 추가// Threshold: -30dB, Ratio: 4:1, Attack: 50ms, Release: 300ms// Music 그룹의 "Send" → Voice_Duck으로 전송
// 코드에서 Duck 양 제어public void SetDialogueDucking(bool active){ float targetDb = active ? -10f : 0f; StartCoroutine(FadeMixerParam("MusicDuck", targetDb, 0.3f));}
IEnumerator FadeMixerParam(string param, float target, float duration){ _mixer.GetFloat(param, out float current); float elapsed = 0f;
while (elapsed < duration) { elapsed += Time.deltaTime; float val = Mathf.Lerp(current, target, elapsed / duration); _mixer.SetFloat(param, val); yield return null; } _mixer.SetFloat(param, target);}Audio Mixer는 그룹 계층 → 스냅샷 → 노출된 파라미터 순서로 설계하세요. 볼륨은 반드시 Mathf.Log10(normalized) * 20으로 선형→dB 변환해서 전달하고, 다이나믹 믹싱은 스냅샷 블렌딩으로 처리하면 코드에서 각 파라미터를 개별 제어하는 것보다 훨씬 깔끔합니다. Duck Volume 이펙트로 대화 중 BGM 자동 감쇄를 Mixer 수준에서 처리하면 코드 복잡도를 줄일 수 있습니다.