본문 바로가기
게임 개발 일지/내일배움캠프 TIL

[Unity] Scene이 여러 개인 게임의 SoundManager

by 빛하_ 2024. 2. 22.

 

Scene이 여러 개인 게임에서 BGM이 다음 씬으로 넘어가더라도 끊기지 않고 계속 재생시키고 싶은 경우가 있다.

SoundManager.cs 라는 스크립트를 이용해 게임 시작 시 SoundManager를 오브젝트 형태로 생성시켜주고 DontDestroyOnLoad 처리를 해주면 씬이 넘어가더라도 해당 오브젝트(Audio Souce)를 파괴하지 않고 유지할 수 있다.

 

 

// SoundManager.cs

using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;

public class SoundManager : MonoBehaviour
{
    // 오디오 소스
    private AudioSource bgmPlayer;
    private List<AudioSource> sfxPlayer = new List<AudioSource>();
    private AudioMixer audioMixer;

    public void SoundInit()
    {
        GameObject musicObject = GameObject.Find("SoundManager");

        if (musicObject == null)
        {
            musicObject = new GameObject("SoundManager");
            musicObject.GetOrAddComponent<AudioSource>();
        }

        Object.DontDestroyOnLoad(musicObject);
        bgmPlayer = Util.GetOrAddComponent<AudioSource>(musicObject);

        for (int i = 0; i < 10; i++)
        {
            AudioSource temp = musicObject.AddComponent<AudioSource>();
            sfxPlayer.Add(temp);
        }

        PlayBGM("Battle_Normal_EW01_B", 0.1f);
    }

    public void SoundUpdate()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Main.SoundManager.PlaySFX("SFX_Click", 0.5f);
        }
    }

    public void PlayBGM(string bgmName, float volume)
    {
        bgmPlayer.clip =  Resources.Load<AudioClip>($"Sounds/BGM/{bgmName}");
        if (bgmPlayer.clip != null)
        {
            bgmPlayer.volume = volume;
            bgmPlayer.Play();
            bgmPlayer.loop = true;
        }
    }

    public void PlaySFX(string sfxName, float volume)
    {
        AudioClip clip = Resources.Load<AudioClip>($"Sounds/SFX/{sfxName}");
        for (int i = 0; i < sfxPlayer.Count; i++)
        {
            if (sfxPlayer[i].isPlaying)
            {
                continue;
            }
            else
            {
                sfxPlayer[i].volume = volume;
                sfxPlayer[i].PlayOneShot(clip);
            }
        }
    }

 

* PlayBGM 메서드를 이용해 배경음악을 설정할 수 있다.

string bgmName 은 resources 폴더에 있는 음악의 제목을 정확히 string 값으로 가져오는 역할을 하고

float volume으로 볼륨을 조절한다.

 

* PlaySFX 메서드를 이용해 효과음을 설정할 수 있다.

효과음의 경우 상시 재생되는 것이 아니라, 유저의 input 또는 캐릭터가 특정 모션을 취할 때 등 조건이 필요하다.

따라서 메서드를 발동시키기 위한 조건문을 담는 메서드인 SoundUpdate()를 만들었다.

 

 

만약 다음 씬으로 넘어갔을 때 다른 음악을 재생시키고 싶다면?

이번 프로젝트의 경우 IntroScene, SelectScene, GameScene 등 배경음악 변환이 필요한 경우가 많았다.

배경음악을 오랜시간 씬에서 홀드하고 있는 경우가 아니라 씬 전환이 빠르게 이루어지는 게임이기 때문에

초기에 생성한 SoundManager 오브젝트를 파괴하고 재생성하는 것은 불편하다고 생각했다.

따라서 기존에 작동하고 있는 SoundManager를 유지하되, 각 Scene에서 Init 하는 부분에 배경음악 리소스를 변경하는 방법을 채택했다.

SoundManager 자체가 싱글톤 형식을 띄고 있기 때문에 별다른 초기화 작업 없이 바로 Main.SoundManager로 불러와서 코드를 간소화할 수 있었다.

 

 

댓글