게임 설정창에서 슬라이더를 통해 소리를 조절하는 기능을 구현해 보도록 하자.
전체 볼륨 뿐만 아니라, 효과음과 배경음 등 사운드 그룹을 나누어 따로 조절할 수도 있다.
AudioMixer 세팅하기
프로젝트 창에서 Assets > Create > Audio > AudioMixer를 통해 새로운 AudioMixer를 생성할 수 있다.
AudioMixer는 유니티에서 AudioSources에서 생성하는 오디오 시그널을 더 복잡하게 라우팅하고 믹싱하는 AudioSources를 참조할 수 있는 에셋이다.
쉽게 말해서 여러 오디오 소리를 한 곳으로 모아서, 볼륨이나 효과를 한꺼번에 조절해줄 수 있게 해주는 '음향 조절기'이다.
- AudioSource → 실제로 소리를 재생하는 스피커
- AudioMixer → 여러 AudioSource에서 나오는 소리를 한데 모아 조절하는 믹서기

만들어둔 AudioMixer를 스크립트에서 제어하려면 반드시 ‘Expose to Script’ 설정을 해줘야 한다.
이 기능을 통해 AudioMixer의 파라미터 이름을 사용자가 직접 지정할 수 있고, 그 이름을 이용해 코드에서 볼륨이나 효과 값을 제어할 수 있게 된다.


AudioManager 작성
이제 실제로 볼륨을 바꿔줄 매니저를 만들어야 한다.
AudioManager은 슬라이더 입력값을 dB 단위로 변환해 실시간으로 볼륨을 조절하며, 씬 전환 시에도 유지되는 싱글톤 구조로 동작한다.
1️⃣ 주요 변수
[SerializeField] private AudioMixer mixer;
[SerializeField] private string bgmParam = "BGMVol";
[SerializeField] private string sfxParam = "SFXVol";
- 오디오 믹서 에셋을 코드에서 제어하기 위해 AudioMixer형 변수를 선언
- BGM과 효과음을 각각 따로 제어하기 위해, AudioMixer에서 Expose한 파라미터를 연결
2️⃣ 초기 설정
void Awake()
{
if (Instance != null) { Destroy(gameObject); return; }
Instance = this;
DontDestroyOnLoad(gameObject);
CurrentBgm = 0.5f;
CurrentSfx = 0.5f;
ApplyBgm(CurrentBgm);
ApplySfx(CurrentSfx);
}
- 모든 씬에서 사용하기 위해 싱글톤으로 생성
- 시작시 기본 볼륨을 미리 초기화
3️⃣ 실시간 반영 기능
public void PreviewBgm(float v) { CurrentBgm = Mathf.Clamp01(v); ApplyBgm(CurrentBgm); }
public void PreviewSfx(float v) { CurrentSfx = Mathf.Clamp01(v); ApplySfx(CurrentSfx); }
- 슬라이더가 움직일 때 즉시 오디오 볼륨이 반영되도록 하는 메서드이다.
- Mathf.Clamp01() 메서드를 통해 값을 0~1 사이로 제한
4️⃣ 실제 볼륨 적용 메서드
void ApplyBgm(float v) => mixer.SetFloat(bgmParam, v <= 0.0001f ? -80f : 20f * Mathf.Log10(v));
void ApplySfx(float v) => mixer.SetFloat(sfxParam, v <= 0.0001f ? -80f : 20f * Mathf.Log10(v));
- 20 * Log10(v) 공식을 이용하여, 슬라이더의 0~1 값을 데시벨(dB) 로 변환한다.
- 0에 가까운 값은 -80dB로 고정해 무음 처리를 한다.
- 이때, 조건을 '0보다 작거나 같음'으로 지정하면 log10(0)은 무한대가 돼서 오류가 발생한다.
소리 설정 UI 스크립트 작성
AudioManager에서 오디오 제어 기능을 구현했다면, 이제 설정 UI에서 사용자의 슬라이더 입력을 AudioManager로 전달하여
BGM과 효과음 볼륨을 실시간으로 조절할 수 있도록 해야 한다.
이를 위해 설정창의 패널을 관리하고, 슬라이더 이벤트를 통해 오디오 값을 즉시 반영하는 UI 제어 스크립트가 필요하다.
1️⃣ 주요 변수
[SerializeField] private GameObject settingPanel;
[SerializeField] private Slider bgmSlider;
[SerializeField] private Slider sfxSlider;
- 실제 UI 요소(Panel, Slider)를 코드와 연결하는 변수이다.
2️⃣ 설정창 열기
public void OpenPanel()
{
startBgm = AudioManager.Instance.CurrentBgm;
startSfx = AudioManager.Instance.CurrentSfx;
bgmSlider.SetValueWithoutNotify(startBgm);
sfxSlider.SetValueWithoutNotify(startSfx);
settingPanel.SetActive(true);
}
- 현재 오디오 값을 불러와 슬라이더를 갱신한다.
- SetValueWithoutNotify()는 UI만 갱신하고 불필요한 이벤트 호출을 막기 위해 사용한다.
- 슬라이더를 움직일 때는 OnValueChanged 이벤트가 호출된다.
- 하지만 슬라이더 값을 코드로 변경할 때(bgmSlider.value = startBgm;)도 Unity가 값이 바뀌었다고 인식해 자동으로 OnValueChanged 이벤트를 실행한다.
- 이미 현재 음량이 적용된 상태에서 슬라이더 UI를 갱신할 때 이런 이벤트가 또 발생하는 것은 비효율적이므로,
SetValueWithoutNotify()를 사용해 UI 위치만 갱신하고 이벤트는 발생시키지 않도록 처리한다.
3️⃣ 실시간 볼륨 반영
public void OnBgmChanged(float v) => AudioManager.Instance.PreviewBgm(v);
public void OnSfxChanged(float v) => AudioManager.Instance.PreviewSfx(v);
- 슬라이더가 움직일 때마다 AudioManager에 값을 전달
- 볼륨이 즉시 조정되어 미리듣기처럼 실시간으로 반영된다.

PlayerPrefs를 이용한 로컬에 음량 값 저장하기
게임을 껐다 켜도 사용자가 설정한 볼륭이 유지되길 원할 수 있다.
그럴때는 Unity에서 제공하는 PlayerPrefs 기능을 활용하면 된다.
PlayerPrefs는 간단한 데이터를 로컬에 저장해 두는 시스템으로, 볼륨처럼 숫자형 설정값을 저장하기에 적합하다.
/// 로컬 저장 x
/// 확인 버튼 시 저장하지 않고, 단순 반영만 한다.
public void SaveVolumes()
{
ApplyBgm(currentBgm);
ApplySfx(currentSfx);
}
- 로컬에는 저장하지 않는 현재 코드 구조
private const string BGM_KEY = "vol_bgm"
private const string SFX_KEY = "vol_sfx"
// 로컬 저장 메서드. 게임을 재시작해도 변경된 데이터가 유지된다.
public void SaveVolumes()
{
PlayerPrefs.SetFloat(BGM_KEY, currentBGM)
PlayerPrefs.SetFloat(BGM_KEY, currentBGM)
PlayerPrefs.Save();
}
- 한 번 조정한 음량이 게임을 다시 켜도 그대로 유지된다.
실제 테스트




적용이 잘 되는 모습이다..! ^^
'Unity' 카테고리의 다른 글
| [유니티] 더 나은 코드를 위해, 코드간의 결합도 낮추기 (0) | 2025.12.04 |
|---|---|
| [유니티] 비트 플래그(Bit Flag)를 사용한 다중 상태 관리 구현하기 (0) | 2025.10.18 |