Skip to content

develop‐Sound

Seong Hyeok OH edited this page Jul 19, 2023 · 3 revisions

준비

  • 모든 씬에 사운드가 적용이 되도록, Loading 씬 계층창에 두고 오디오소스를 추가한다. 버튼 클릭 사운드와 BGM 사운드를 추가하낟.
  • OptionalController에 넣을 드롭 다운 오브젝트 준비
  • 사운드가 필요한 부분에서 SoundManager를 통해 재생

사용 방법

  • PlayBgm은 씬에 맞게 재생, 이어서 재생할 경우 아무 조작이 필요 없고, 노래를 바꿔야하는 경우 StopBGM 사용
  • 버튼 클릭 사운드는 해당 ButtonScript을 적용하고, 다른 사운드 필요 시 인스펙터창에 추가한다.
  • 무기와 캐릭터는 고유의 오디오 소스로 사운드 재생
  • 상황에 맞게 PlaySoundEffect(원하는 사운드 클립을 재생), PlayRateSound(소리 크기에 일정 크기를 곱함), PlayOverlapSound(한 사운드 임팩트가 끝나야 다음 사운드 임팩트가 재생)을 실행

스크립트

  • SoundManager

using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;

public class SoundManager : MonoBehaviour
{
    public static SoundManager instance;

    public float BgmVolume = 1.0f; // BGM 볼륨
    public float SoundEffectVolume = 1.0f; // 사운드 이펙트 볼륨
    public AudioClip ButtonSoundClip; // 버튼 소리 파일
    public AudioClip[] Bgm;
    public AudioSource AudioSource; // 소리를 재생할 오디오 소스

    private string mCurrentScene; // 현재 씬의 이름을 저장할 변수
    private AudioClip currentSoundEffect;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else if (instance != this)
        {
            Destroy(gameObject);
            return;
        }

        DontDestroyOnLoad(gameObject);
        AudioSource = GetComponent();
    }
    private void Start()
    {
        mCurrentScene = SceneManager.GetActiveScene().name;
        SceneManager.sceneLoaded += OnSceneLoaded;
        PlayBgm(mCurrentScene);
    }
    #region
    private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        if (scene.name != mCurrentScene)
        {
            if (scene.name == "InGame")
            {
                // 이전 씬과 다른 BGM인 경우 새로운 BGM 재생
                StopBgm();
                PlayBgm(scene.name);
            }
            else if (scene.name == "GameResult")
            {
                StopBgm();
                PlayBgm(scene.name);
            }
            else
            {
                // 이전 씬과 동일한 BGM인 경우 이어서 재생
            }
        }
    }
    private void PlayBgm(string sceneName)
    {
        if (AudioSource == null)
        {
            Debug.LogError("AudioSource 컴포넌트가 없습니다!");
            return;
        }

        AudioClip bgmClip;
        if (sceneName == "InGame")
        {
            // InGame 씬에 진입한 경우
            bgmClip = Bgm[(int)Enums.EBgm.Stage1]; // InGame 씬에 해당하는 BGM
        }
        else
        {
            // 나머지 씬에 진입한 경우
            bgmClip = Bgm[(int)Enums.EBgm.BGM]; // 나머지 씬에 해당하는 BGM
        }

        AudioSource.clip = bgmClip;
        AudioSource.volume = BgmVolume;
        AudioSource.Play();
    }
    private void StopBgm()
    {
        AudioSource.Stop();
    }
    public void PlayButtonSound()
    {
        AudioSource.PlayOneShot(ButtonSoundClip, SoundEffectVolume);
    }
    public void PlaySoundEffect(AudioClip soundEffectClip)
    {
        AudioSource.PlayOneShot(soundEffectClip, SoundEffectVolume);
    }
    public void PlayRateSound(AudioClip soundEffectClip)
    {
        AudioSource.PlayOneShot(soundEffectClip, SoundEffectVolume * Constants.SOUND_EFFECT_RATE);
    }
    public void PlayOverlapSound(AudioClip soundEffectClip)
    {
        if (currentSoundEffect != null && currentSoundEffect == soundEffectClip)
        {
            // 현재 사운드 이펙트가 이미 재생 중인 경우, 중첩 재생을 피하기 위해 종료합니다.
            return;
        }
        currentSoundEffect = soundEffectClip;
        AudioSource.PlayOneShot(soundEffectClip, SoundEffectVolume);

        StartCoroutine(ResetCurrentSoundEffect(soundEffectClip.length));
    }
    private IEnumerator ResetCurrentSoundEffect(float delay)
    {
        yield return new WaitForSeconds(delay);
        currentSoundEffect = null;
    }
    #endregion
}

  • ButtonScript

using UnityEngine;
using UnityEngine.UI;

public class ButtonScript : MonoBehaviour
{
    [SerializeField] AudioClip mClip;
    private Button mButton;

    private void Start()
    {
        mButton = GetComponent();
        mButton.onClick.AddListener(PlayButtonSound);
    }
    private void PlayButtonSound()
    {
        if (mClip == null)
        {
            SoundManager.instance.PlayButtonSound();
        }
        else
        {
            SoundManager.instance.PlaySoundEffect(mClip);
        }
    }
}

  • OptionalController

using UnityEngine;
using UnityEngine.UI;

public class OptionalController : MonoBehaviour
{
    [SerializeField] Slider mBgmSlider;
    [SerializeField] Slider mSoundEffectSlider;
    [SerializeField] Toggle mVFXToggle;
    [SerializeField] Toggle mFullScreenToggle;
    [SerializeField] Toggle mShowDamageToggle;
    [SerializeField] Toggle mHideStageToggle;
    private SoundManager mSoundManager;

    private void Start()
    {
        mSoundManager = SoundManager.instance;

        // 저장된 설정 값을 슬라이더에 반영
        LoadSettings();

        mBgmSlider.onValueChanged.AddListener(OnBgmVolumeChanged);
        mSoundEffectSlider.onValueChanged.AddListener(OnSoundEffectVolumeChanged);
        mVFXToggle.onValueChanged.AddListener(OnVFXToggleChanged);
        mFullScreenToggle.onValueChanged.AddListener(OnFullScreenToggleChanged);
        mShowDamageToggle.onValueChanged.AddListener(OnShowDamageToggleChanged);
        mHideStageToggle.onValueChanged.AddListener(OnHideStageToggleChanged);
    }
    private void LoadSettings()
    {
        // BGM 볼륨 로드
        float bgmVolume = mSoundManager.BgmVolume;
        mBgmSlider.value = bgmVolume;

        // 사운드 이펙트 볼륨 로드
        float soundEffectVolume = mSoundManager.SoundEffectVolume;
        mSoundEffectSlider.value = soundEffectVolume;
    }
    public void OnBgmVolumeChanged(float value)
    {
        // BGM 볼륨 값을 변경
        mSoundManager.BgmVolume = value;
        SoundManager.instance.AudioSource.volume = value;
    }
    public void OnSoundEffectVolumeChanged(float value)
    {
        // 사운드 이펙트 볼륨 값을 변경
        mSoundManager.SoundEffectVolume = value;
    }
    public void OnFullScreenToggleChanged(bool value)
    {
        if (value)
        {
            Screen.SetResolution(Screen.currentResolution.width, Screen.currentResolution.height, true);
        }
        else
        {
            Screen.SetResolution(800, 600, false);
        }
    }
}

Clone this wiki locally