내일배움캠프/Unity Final Projcet
[Untiy] AudioMixer 기반의 BGM & SFX 사운드 매니저 제작하기
danpat77
2025. 4. 22. 20:33
이번에는 사운드를 체계적으로 관리하기 위해
AudioMixer를 기반으로 한 BGM / SFX 분리형 사운드 매니저를 제작해봤습니다.
슬라이더로 실시간 볼륨 조절도 가능하고,버튼으로 음소거/해제 시 아이콘이 바뀌는 기능까지 구현했습니다.
구현 목표 및 개요
- BGM과 SFX를 AudioMixer를 통해 개별 제어
- 슬라이더로 실시간 볼륨 조절
- 음소거 버튼 클릭 시 아이콘 변경
- 씬 전환에도 BGM 유지
- 슬라이더 값 0일 경우에도 자동으로 음소거 아이콘 반영
1. AudioMixer 설정
- MainMixer 생성
Assets > Create > Audio > Audio Mixer - Group 분리
Master 하위에 BGM, SFX 그룹 생성 - Volume 파라미터 Expose
각 그룹의 Volume 슬라이더 → 우클릭 → Expose to script- 이름: BGMVolume, SFXVolume
- AudioSource 연결
오디오 출력용 AudioSource 2개 생성 후 각각 Output에 BGM / SFX 연결
2.구현된 기능
2-1. 슬라이더 볼륨 조절
Mathf.Log10(volume) * 20을 통해 AudioMixer가 기대하는 dB 기준으로 정확한 제어
2-2. 음소거 버튼
음소거 버튼 클릭 시 -80dB 설정, 다시 누르면 이전 볼륨 복원
2-3. 아이콘 자동 전환
- 음소거 상태이면 🔇
- 슬라이더 값 0일 경우도 🔇
- 음량이 살아 있으면 🔊
2-4. 씬 전환 후에도 유지
DontDestroyOnLoad() 적용으로 BGM 유지
3. 핵심 코드 정리
3-1. 사운드 타입 enum 정의
public enum BGMType
{
Main,
Battle,
// 필요시 확장 가능
}
public enum SFXType
{
ButtonClick,
Gacha,
TurretShoot,
Explosion,
EnemyDie
}
- BGMType과 SFXType으로 사운드 종류를 구분합니다.
- 이후 코드에서 PlayBGM(BGMType.Main)처럼 사용하면, 오타 없이 안전하게 사운드를 관리할 수 있습니다.
3-2. SoundManager.cs (요약본)
public class SoundManager : Singleton<SoundManager>
{
[SerializeField] private AudioSource bgmSource;
[SerializeField] private AudioSource sfxSource;
[SerializeField] private AudioMixer audioMixer;
private float lastBgmVolume = 0.8f;
private float lastSfxVolume = 0.8f;
private bool isBgmMuted = false;
private bool isSfxMuted = false;
public bool IsBGMMuted => isBgmMuted;
public bool IsSFXMuted => isSfxMuted;
private Dictionary<BGMType, AudioClip> bgmDict = new();
private Dictionary<SFXType, AudioClip> sfxDict = new();
public void PlayBGM(BGMType type, bool loop = true)
{
if (bgmDict.TryGetValue(type, out var clip))
{
bgmSource.clip = clip;
bgmSource.loop = loop;
bgmSource.Play();
}
}
public void PlaySFX(SFXType type)
{
if (sfxDict.TryGetValue(type, out var clip))
sfxSource.PlayOneShot(clip);
}
}
- Dictionary<BGMType, AudioClip> 구조로 관리되기 때문에, 사운드 키의 충돌이나 중복 위험 없이 효율적으로 접근할 수 있습니다.
- enum을 쓰면 코드 자동완성도 지원되기 때문에, 관리가 매우 편리해집니다.
3-3. UI 연동 예시 - SoundController.cs
private void UpdateIcon(Image icon, float volume, bool isMuted)
{
bool isEffectivelyMuted = isMuted || volume <= 0.0001f;
icon.sprite = isEffectivelyMuted ? iconSoundOff : iconSoundOn;
}
- 슬라이더 값이 0이 되거나 음소거 상태일 경우 자동으로 아이콘 변경
- UI와 논리 상태를 명확히 연결해주는 역할을 합니다
4. 적용 화면 예시
- 슬라이더를 조절하면서 소리가 즉시 반응
- 버튼 클릭으로 음소거 및 복구
- 음소거 상태에 따라 아이콘도 자동 전환
마무리
번 작업에서는 단순히 소리를 내는 기능을 넘어서,
볼륨 상태 관리, UI 반응, 재생 상태 유지 등
게임 전반에서 필요한 사운드 구조를 체계적으로 구성해볼 수 있었습니다.
특히 SoundManager와 SoundController의 역할을 분리하면서
UI와 로직의 책임을 나누는 연습도 되었습니다.
앞으로도 이 구조를 기반으로 씬별 BGM 전환, 페이드 효과, 스테이지 클리어 시 효과음 재생 등으로 확장할 수 있을 것 같아 기대가 됩니다.