GameDev/Cubidom

Cubidom - BGM 넣기

SMNNMN 2026. 4. 18. 23:57

게임 사운드의 하나인 BGM을 넣을 것이다. 

유니티 에셋에서 사운드를 구했다.

사용한 에셋 

https://assetstore.unity.com/packages/audio/music/electronic/rpg-puzzle-game-music-w-music-script-

https://assetstore.unity.com/packages/audio/music/complete-music-collection-free-edition-119129

https://assetstore.unity.com/packages/audio/music/free-music-for-puzzle-games-152395

배경음악 만들기

메인화면, 게임이 시작될때, 게임 레벨에 따른 배경음악을 만들 것이다.

메인화면과, 게임 시작, 다음 레벨로 배경음악이 전환될때, 페이드 인/아웃으로 사운드의 크기를 변화할 것이다.

또한 일시정지 상태가 되면 자체적으로 배경음악소리가 줄어들게끔 할 것 이다.

 

1 : Easy 1,2

2 : Easy 3,4 , Normal 3

3 : Normal 1,2 , Hard 3,4

4 : Normal 4, Hard 1,2

5: Easy 5, Normal 5, Hard 5

 

기본적인 Inspector 설정은 이런식으로 구성되어있다.

AudioManage에는 Audio Manager 스크립트가 있고, 자식오브젝트로 두 오디오를 가진다.

두 하위 오디오는 Audio Source 컴포넌트를 가지고 있으며, BackGround와 달리 Effect는 루프가 해제되어있다.

 

AudioManager

using System.Collections;
using UnityEngine;

public class AudioManager : MonoBehaviour
{
    [SerializeField] AudioSource backGroundAudio; // 배경음 담당 오디오
    [SerializeField] AudioSource effectAudio; // 효과음 담당 오디오

    private Coroutine myCoroutine;

    private static AudioManager instance;
    public static AudioManager Instance
    {
        get { return instance; }
    }
    private void Awake()
    {
        if(instance == null)
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
    public void BGMPlay(AudioClip clip)
    {
        backGroundAudio.clip = clip;
        backGroundAudio.Play();
        if (myCoroutine != null)
        {
            StopCoroutine(myCoroutine);
        }
        myCoroutine = StartCoroutine(BGMFade(true));
    }

    // 배경음악 페이드인/아웃 하는 함수
    IEnumerator BGMFade(bool type) // type = 1 : FadeIn / type = 0 : FadeOut
    {
        float t = 0;
        float duration,end;
        float start = backGroundAudio.volume;
        switch(type)
        {
            case true: duration = 5; end = 1; break;
            case false: duration = 3; end = 0; break;
        }
        while(t < duration)
        {
            t += Time.deltaTime;
            backGroundAudio.volume = Mathf.Lerp(start, end, t / duration);
            yield return null;
        }
    }
}

먼저 싱글톤이 들어가있고, BGMPlay에서 AudioClip을 변수로 받아, 오디오를 AudioSource의 clip에 넣고, 실행한다. 

만약 다른 BGM이 실행중이라면, 실행중인 BGM을 중단하고, 새로운 BGM으로 전환하게끔 되어있다.

BGMFade의 경우 bool값으로 fadeIn/Out을 구분한다. AudioSource의 volume에 접근하여, 일정시간동안 0 또는 1이 되도록 한다. (끄기/켜기)

 

게임 시작시 BGM 호출

게임이 시작되었을 때, 현재 레벨과 스테이지를 판단하여, 실행할 오디오를 Resources를 통해 찾아서 실행시킨다. 

    private void Start()
    {
        GameManager.Instance.gameStart += StartBGM;
    }
    private void OnDisable()
    {
        GameManager.Instance.gameStart -= StartBGM;
    }   
   void StartBGM() // 게임이 시작될 때, 실행할 오디오를 구하는 함수
    {
        int level = GameManager.Instance.enemyLevel;
        int stage = GameManager.Instance.enemyStage;

        int id = level * 1000 + stage;
        Debug.Log("id는 : " + id);
        if(id == 1001 || id == 1002)
        {
            BGMData("BGM/Battle Song");
        }
        else if(id == 1003 || id == 1004 || id == 2003)
        {
            BGMData("BGM/Boss Fight");
        }
        else if(id == 2001 || id == 2002 || id == 3003 || id == 3004)
        {
            BGMData("BGM/Crazy Puzzle Electronic");
        }
        else if(id == 2004 || id == 3001 || id == 3002)
        {
            BGMData("BGM/Entering a Town");
        }
        else if(id == 1005 || id == 2005 || id == 3005)
        {
            BGMData("BGM/Underwater (Electronic, Action)");
        }
    }
    void BGMData(string name) // BGM 데이터를 찾고, 넣는 함수
    {
        AudioClip clip = Resources.Load<AudioClip>(name); 
        BGMPlay(clip);
        Debug.Log("~~~~~~~~~~~~~~~" + clip);
    }

 

 

게임 종료 및 설정 BGM FadeOut

게임이 종료 되었을 때나 설정창을 열었을 때, BGM이 FadeOut되는 기능을 추가했다.

 AudioManager

    private void Start()
    {
        GameManager.Instance.gameStart += StartBGM;
        GameManager.Instance.gameFinish += BGMFinish;
    }
    private void OnDisable()
    {
        GameManager.Instance.gameStart -= StartBGM;
        GameManager.Instance.gameFinish -= BGMFinish;
    }
	public void BGMFinish() // BGM 소리가 감소되야 할때 호출되는 함수. 게임 종료, 설정
    {
        if(myCoroutine != null)
        {
            StopCoroutine(myCoroutine);
        }
        myCoroutine = StartCoroutine(BGMFade(false));
    }

BGMFinish로 현재 실행중인 BGM을 FadeOut 시키는 코드를 작성했다.

GameManager의 gameFinish 델리게이트에 구독하여, 게임이 종료될 때, 실행되게끔 하였다.

 

GameManager

설정 상태일 때, BGMFinish을 호출하여 소리르 줄였다.

    public void GameStop(bool myBool) // 게임을 정지하는 단계
    {
        if(myBool)
        {
            myState = GameState.STOP;
            AudioManager.Instance.BGMFinish();
        }
        else
        {
            myState = GameState.START;
            AudioManager.Instance.StartBGM();
        }
    }

 

AudioManager

    IEnumerator BGMFade(bool type) // type = 1 : FadeIn / type = 0 : FadeOut
    {
        float t = 0;
        float duration,end;
        float start = backGroundAudio.volume;
        switch(type)
        {
            case true: duration = 5; end = 1; break;
            case false: duration = 0.5f; end = 0.2f; break;
        }
        while(t < duration)
        {
            // t += Time.deltaTime;
            t += Time.unscaledDeltaTime;
            backGroundAudio.volume = Mathf.Lerp(start, end, t / duration);
            yield return null;
        }
    }

먼저 FadeOut이 될때의 속도와, 최소 볼륨값을 수정하였다.

t에 Time.deltaTime을 더하게되면 Time.timeScale이 0이 되었을 때, 소리가 줄어들지 않아, Time.unscaledDeltaTime을 더한다.

 

중복 BGM 재사용 확인

BGM이 실행중일 때, 한번더 같은 BGM이 실행된다면 다시 오디오 초기화 되기 때문에, 현재 진행중인 BGM을 확인하여 같다면 다시 실행되지 않게끔 코드를 추가했다.

        private AudioClip playingBGM; // 현재 실행중인 BGM

    public void BGMPlay(AudioClip clip) // BGM 실행함수
    {
        backGroundAudio.clip = clip;

        if(playingBGM != clip)
        {
            backGroundAudio.Play();
        }

        if (myCoroutine != null)
        {
            StopCoroutine(myCoroutine);
        }
        myCoroutine = StartCoroutine(BGMFade(true));
        playingBGM = clip;
    }

 

메인 화면 BGM

메인화면일 때도 특정 BGM이 실행되게끔 기능을 넣어준다.

AudioManager

    
        private void Start()
    {
        GameManager.Instance.gameStart += StartBGM;
        GameManager.Instance.gameFinish += BGMFinish;
        GameManager.Instance.mainScene += MainBGM;

        MainBGM();
    }
    private void OnDisable()
    {
        GameManager.Instance.gameStart -= StartBGM;
        GameManager.Instance.gameFinish -= BGMFinish;
        GameManager.Instance.mainScene -= MainBGM;
    }
    public void MainBGM() // 메인 화면에서 실행될 BGM
    {
        BGMPlay(Resources.Load<AudioClip>("BGM/Sunset on the Bay (Electronic, Synthwave)"));
    }

게임 처음에는 Start에서 실행시키고, 이후부터는 GameManager의 mainScene 구독을 통해서 실행시킨다.