본문 바로가기
Unity/사운드

슬라이드 바로 사운드 조절하기

by Jinger 2023. 6. 1.

서론

    사운드(BGM, Effect Sound 등) 소리를 관리해 주는 기능들이 모든 게임에 기본적으로 탑재되어 있다. 그중 슬라이드 바로 조절하는 방법에 대해 알아보자.


관리

    사운드는 보통 GameManager 혹은 SoundManager를 통해 관리가 된다. GameManager는 게임의 주요 로직을 관리하는 클래스이다. 게임 진행 상태, 게임 플레이어, 적의 움직임, 충돌 감지, 게임 상태 변화 등과 같은 게임 로직을 처리한다. GameManager는 게임의 주요 컨트롤러 역할을 수행하며, 게임 진행을 제어하고 조정한다. 작은 규모의 게임의 경우 사운드 크기 조절은 게임의 로직으로도 볼 수 있고, 큰 분류를 하기 모호하므로 이곳에서 관리를 하지만, 중 규모 이상부터 GameManager의 하는 역할이 너무나 많기 때문에 SoundManager를 통해 관리를 한다. SoundManager는 게임 내에서 사운드와 관련된 기능을 관리하는 클래스이다. 주로 배경 음악(BGM) 재생, 사운드 이펙트 재생, 볼륨 조절 등의 작업을 처리한다. SoundManager는 게임의 오디오 리소스를 관리하고, 사운드 재생을 위한 인터페이스를 제공한다.

      아래  SoundManager는 다음 예시에 사용될 코드이다. 아래 예는 마스터 볼륨이 있을 경우의 예이다. 만약 마스터 볼륨을 사용한다면 예시 코드와 같이 (마스터 볼륨의 값 * 조절한 볼륨의 값)으로 소리의 크기를 조절하여 사용하면 된다. 반대로, 마스터 볼륨을 사용하지 않는다면, masterVolume을 지워 사용하면 된다. 

using UnityEngine;

public class SoundManager : MonoBehaviour
{
    public static SoundManager instance;
    public float MasterVolume { get; set; } = 1.0f;
    public float BgmVolume { get; set; } = 1.0f;
    public float SoundEffectVolume { get; set; } = 1.0f;

    private AudioSource _bgmAudioSource;
    private AudioSource _soundEffectAudioSource;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
            _bgmAudioSource = gameObject.AddComponent<AudioSource>();
            _soundEffectAudioSource = gameObject.AddComponent<AudioSource>();
        }
        else if (instance != this)
        {
            Destroy(gameObject);
            return;
        }
    }
    public void PlayBGM(AudioClip bgmClip)
    {
        _bgmAudioSource.clip = bgmClip;
        _bgmAudioSource.volume = MasterVolume * BgmVolume;
        _bgmAudioSource.loop = true;
        _bgmAudioSource.Play();
    }
    public void StopBGM()
    {
        _bgmAudioSource.Stop();
    }
    public void PlaySoundEffect(AudioClip soundEffectClip)
    {
        _soundEffectAudioSource.PlayOneShot(soundEffectClip, MasterVolume * SoundEffectVolume);
    }
}

   이 때, "DontDestoryOnLoad"를 이용해서 모든 씬에서 해당 사운드 크기를 유지하고 같은 오디오 소스에서 출력하게 한다. 만약, 한 오디오 소스가 모든 사운드를 관리하면, 매번 크기 조절하는 데 어려움을 겪기에 적절한 수로 이용해야 한다.

    추가적으로 다음 예시를 따라 하기 위해 슬라이드 바 생성과 다음과 같이 "SoundManager"를 빈(Empty) 오브젝트로 생성 후 위 스크립트 적용해 주면 준비는 끝이다. (오디오 소스는 스크립트에서 추가하므로 넣을 필요가 없다.)


슬라이드 바

    UI의 "slider"는 자동적으로 드래그 및 화살표(WASD)로 조절이 가능하지만, 조절한 값을 스크립트로 전달을 해줘야 한다. 아래와 같이 스크립트를 짜고, 슬라이드 바에 적용한 뒤, 슬라이드 바를 인스펙터 창에 스크롤해 놓으면 작동이 된다. 하지만 해당 스크립트는 오직 한 개의 슬라이드 바를 다룰 때 사용이 되는 예이다. 만약 여러 슬라이드바를 사용한다면, 스크립트를 여러 개를 만들거나, 해당 클래스를 추상화 작업을 해야 하는 번거로움이 있다. 이 방식을 유지하면서 개편한 방식이 "Option Controller" 스크립트이다.

using UnityEngine;
using UnityEngine.UI;

public class VolumeSlider : MonoBehaviour
{
    public Slider VolumeSlider; // 슬라이더 UI 컴포넌트

    private void Start()
    {
        // 슬라이더의 값 설정
        VolumeSlider.value = SoundManager.instance._bgmVolume;

        // 슬라이더 값 변경 이벤트에 함수 연결
        VolumeSlider.onValueChanged.AddListener(OnVolumeChanged);
    }

    // 볼륨 변경 이벤트 핸들러
    private void OnVolumeChanged(float value)
    {
        // SoundManager의 BGM 볼륨 값 업데이트
        SoundManager.instance.BgmVolume = value;
        SoundManager.instance._bgmAudioSource.volume = value;
    }
}


옵션

    옵션 전체를 다루는 스크립트 "Option Controller" 정의하여 옵션의 모든 기능들을 정의해 사용할 수 있다. 여기서는 오직 사운드에 관해서만 살펴보자. 옵션에 있는 오브젝트들을 가져오고 위의 "VolumSlider"와 같이 정의된다. 이 스크립트는 클래스 이름과 같이 모든 이름을 관리하는 데 사용하므로, Canvas나 빈 오브젝트에 적용하여 관리한다.

using UnityEngine;
using UnityEngine.UI;

public class OptionController : MonoBehaviour
{
    public Slider bgmSlider;
    public Slider soundEffectSlider;
    public Slider masterVolumeSlider;

    void Start()
    {
        // 저장된 볼륨 값 로드
        bgmSlider.value = SoundManager.instance._bgmVolume;
        soundEffectSlider.value = SoundManager.instance._soundEffectVolume;
        masterVolumeSlider.value = SoundManager.instance._masterVolume;

        // 슬라이더의 값이 변경될 때마다 OnVolumeChanged 메서드를 호출하도록 함
        bgmSlider.onValueChanged.AddListener(OnBgmVolumeChanged);
        soundEffectSlider.onValueChanged.AddListener(OnSoundEffectVolumeChanged);
        masterVolumeSlider.onValueChanged.AddListener(OnMasterVolumeChanged);
    }

    void OnBgmVolumeChanged(float value)
    {
        // BGM 볼륨 값을 변경
        SoundManager.instance.BgmVolume = value;
        SoundManager.instance._bgmAudioSource.volume = value;
    }

    void OnSoundEffectVolumeChanged(float value)
    {
        // 사운드 이펙트 볼륨 값을 변경
        SoundManager.instance.SoundEffectVolume = value;
        SoundManager.instance._soundEffectAudioSource.volume = value;
    }

    void OnMasterVolumeChanged(float value)
    {
        // 마스터 볼륨 값을 변경
        SoundManager.instance.MasterVolume = value;
        SoundManager.instance._bgmAudioSource.volume *= value;
        SoundManager.instance._soundEffectAudioSource.volume *= value;
    }
}


사용 방법

   위와 같이 적용이 되었다면, 직접 사운드를 불러보자. "SoundManager"에서 정의한 PlayBGM 혹은 PlaySoundEffect를 호출하여 사운드를 출력한다. 아래는 사용 예시이다. 해당 오브젝트의 오디오 클립만 가져오면 바로 사용할 수 있다.

SoundManager.instance.PlayBGM(사운드 클립);
SoundManager.instance.PlaySoundEffect(사운드 클립);
using UnityEngine;

public class SoundEffect: MonoBehaviour
{
    [SerializeField] AudioClip _clip;

    public void PlayButtonSound()
    {
        SoundManager.instance.PlaySoundEffect(mClip);
    }
}

주섬주섬

  • GameManager와 SoundManager를 나누는 것은 자유이지만, 객체 지향 5원칙을 고려하여 적절히 적용하길 바란다.
  •  AddListener함수는 버튼, 슬라이드 바와 같은 UI의 이벤트가 부여되지 않았을 때, 스크립트에서 부여해 주는 함수이다.
  • 추가적으로 설정을 하지 않았다면, 소리는 최소 0부터 최대 1 사이의 실수 값을 가진다.
  • 시뮬레이션 돌릴 경우, 위 사례대로라면 SoundManager가 없는 씬에서 시작하면 작동이 되지 않는다.

참고

 

Audio Source 설정

서론 사운드(뮤직, 효과음 등)와 관련된 Audio Source에 대해 낱낱이 알아보자. Audio Source 오디오 소스(Audio Source)는 씬에서 오디오 클립(Audio Clip)을 재생한다. 이 클립은 오디오 리스너(Audio Listener) 또

jinger.tistory.com

 

Events.UnityEvent-AddListener - Unity 스크립팅 API

Add a non-persistent listener to the UnityEvent.

docs.unity3d.com

 

반응형

'Unity > 사운드' 카테고리의 다른 글

PlayerPrefs으로 옵션 값 저장하기  (1) 2023.08.21
Audio Source 설정  (0) 2023.05.30

댓글