카테고리 없음

유니티 Sound Manager와 AudioSource

akama 2024. 9. 28. 18:18

게임 플레이를 하는데 흥미를 유발하는 시스템과 눈길이 계속 가는 아름다운 그래픽만으로 게임의 재미를 줄 수 있지만 이를 극대화 시키는 요소는 사운드라고 생각합니다. 상황에 맞는 BGM(BackGround Music)과 SFX(효과음)이 있어야 게임의 재미와 함께 몰입감을 줄 수 있기 때문입니다. 이번 포스팅에서는 유니티에 음원을 넣고, 이를 사운드 매니저를 통해 스크립트로 제어하는 방법에 대해 알아보겠습니다. 음원을 유니티에 적용하기 위해서는 먼저 음원을 구해야 하는데 그 전에 어느 부분에서 어떤 효과음이 나오고 스테이지에 따른 BGM은 몇 개를 사용할지를 정해야 합니다. 이 부분은 기획단계에서 정해야 작업을 수월하게 할 수 있습니다. 다시 한 번 강조하지만 기획은 게임 제작의 설명서이므로 개발 전에 꼭 기획서를 만드는 습관을 들이는 것이 좋습니다. 

 

1. 음원 찾기 & 음원 구하기

게임을 만들면서 사실 매우 까다로운 요소가 바로 이 음원입니다. 음원 사용 시 저작권 문제가 있기 때문에 유료로 아예 구매해서 사용하거나 저작권이 없는 무료 음원 사이트를 찾아야 합니다. 가장 깔끔한 방법은 돈을 주고 유료 음원을 사용하는 것인데 비용이 만만치 않습니다. 인터넷 유료 사이트나 무료 사이트에서 음원들은 구할 수 있으며 샘플로도 확인이 가능하니 들어보고 라이센스 부분까지 확인하고 사용하시면 됩니다. 또한 유니티 에셋 스토어에서도 음원 부분을 무료 또는 유료로 구할 수 있기 때문에 인터넷과 에셋 스토어 둘 다 활용하면 폭 넓은 탐색을 할 수 있습니다. 괜찮다고 생각하는 음원 사이트를 소개해 드리겠습니다.

AudioStock

 

ボイス・ナレーションの著作権フリー音源・音楽素材 [mp3/WAV] | Audiostock(オーディオストック)

10000件以上のボイス・ナレーション素材一覧。 「Audiostock」では、著作権ロイヤリティフリーの音楽素材が660円から購入・ダウンロード可能です。また、99万点以上の高品質BGM・効果音・ボイ

audiostock.jp

Audiostock은 일본 사이트라서 일본어로 나옵니다. 그러나 요즘 세상 좋아졌습니다. 바로 사이트 번역 기능이 제공되니 한글로 변경해서 탐색이 가능합니다. 일본 사이트답게 일본 성우의 캐릭터 음원이 많이 있습니다. 효과음과 배경음악도 있으니 마음에 드는 음원은 계속 탐색해서 찾아야 합니다. 이 사이트 단점은 일본 유료 사이트이고 심지어 회원 가입을 해야 한다는 점입니다.

 

뮤팟

 

효과음 다운받기 | 프리미엄 배경음악 뮤팟

영상 편집자에게 꼭 필요한 무료 효과음 이걸로 종결! 장면전환, 소리효과와 같은 다양한 효과음들을 획득하세요.

www.mewpot.com

이 사이트는 다양한 배경음악과 효과음이 있으며 한글로 나오기 때문에 쉽게 접근이 가능합니다. 대부분이 유료이지만 유료인 만큼 퀄리티는 괜찮은 편입니다.

 

Splice

 

Royalty-Free Sounds, FX, Presets & More | Splice

Splice is the leading platform for music production offering access to millions of the best royalty-free samples, loops, and presets.

splice.com

음원 샘플이 매우 방대하게 많은 사이트입니다. 이 사이트는 게임 개발을 위해 필요한 음원보다는 음악 작곡을 하는 분들에게 더 유용한 사이트라고 생각합니다. 물론 게임에 필요한 음원을 찾을 수 있지만 사이트이름 대로 사운드 샘플이 세분화 되어 있습니다. 예를 들어 테크노 스타일을 클릭해서 들어가면 테크노에서 쓰일 수 있는 음원들이 drum, fx impacts, deep house 등 다양하게 있어서 골라서 들어보고 사용하는 것 같습니다. 아마도 크리에이터가 필요한 음원을 이 사이트에서 구매한 후 작곡 작업을 할 때 매우 유용한 사이트라고 할 수 있습니다. 이 사이트 샘플은 구독제를 통해 구할 수 있다는 점 참고하시기 바라며 라이센스 부분은 꼭 확인해야 합니다.

 

BGM Factory

 

BGMFACTORY

가장 안전한 배경음악 IP BGM팩토리, 매월 500곡 이상 추가되는 BGM팩토리 자체제작 음원 3만 3천 여 곡을 무제한으로 사용해 보세요!

bgmfactory.com

마지막으로 이 사이트는 다양한 BGM을 가지고 있는 사이트이며 효과음도 있으니 들러서 샘플을 확인해 보는 것도 좋습니다. 대부분 구매해야 하는 유료 사이트이며 이용권도 판매를 하고 있습니다. 특이한 점은 BGM이 어떤 스타일인지를 BPM으로 알려준다는 것입니다. BPM이 높을 수록 비트가 있고 빠른 편이라서 나의 게임 스타일과 유사한 음악을 찾을 때 도움이 됩니다.

 

사실 음원 사이트는 인터넷에 제가 소개한 사이트 외에도 매우 많습니다. 중요한 점은 내가 만드는 게임에 적합한 음원을 찾는 것이 어렵다는 점입니다. 특히 BGM보다 알맞는 효과음을 찾는 것이 쉽지 않으며 무료 음원일 경우에는 퀄리티가 다소 떨어지기 때문에 연습용이 아닌 출시용 게임이라면 돈을 쓰더라도 유료 음원의 이용을 추천합니다. 그러나 내가 만드는 게임이 연습용 게임이라면 에셋 스토어의 무료 음원이나 인터넷에 무료 음원 사이트는 매우 많으니 적당한 음원으로 해도 상관없습니다.

 

2. 음원을 유니티에 적용하고 세팅하기

준비된 음원은 유니티 Project뷰로 드래그 앤 드롭해서 적용 가능합니다. 소스 파일 관리를 위해서 유니티에서 폴더를 하나 만들고 이름을 Sounds라고 바꿔 줍니다. 

유니티에 적용된 음원 wav파일

음원들을 클릭해 보면 Inspector뷰에 해당 음원에 대한 아래와 같은 항목들이 나오게 됩니다. 먼저 디바이스 타입을 설정하시기 바랍니다. 저는 안드로이드로 선택했습니다.

- Force to Mono는 음원을 모노로 변환한다는 것입니다. 체크로 활성화를 시키면 음원의 입체 음향이 사라지면서 오디오가 모노 트랙이 되어 버립니다. 입체적 풍부한 음향은 사라지지만 대신 파일 용량이 줄어드는 장점이 있습니다.

- Load in background는 유니티에서 사용하는 audio clip을 메인 스레드가 아닌 별도의 스레드에서 로드하도록 해서 메인 스레드의 성능 최적화에 도움을 주는 기능입니다. 씬 전환 시 발생하는 로딩에서는 게임 화면에 필요한 리소스들을 로드하는데 이 중 음원 용량을 별도의 스레드에서 처리해주면 좀 더 빠른 씬 전환을 줄 수 있습니다.

- Ambisonic은 오디오의 서라운드 효과로 플레이어에게 입체적 음원을 주는 것으로 주로 VR 같은데 사용됩니다.

- Decompress on load 오디오 파일 로드 시 압축을 해제하는 방식으로 오디오 파일 용량이 큰 경우에는 해제에 사용되는 메모리 사용량도 늘기 때문에 작은 크기의 오디오 파일에 사용합니다.

- Compressed in memory 오디오 파일을 압축된 상태로 메모리에 저장했다가 재생 시 해제하는 방식입니다. 메모리 사용량을 줄이는 장점이 있지만 자주 사용하는 효과음에 사용하면 매번 재생 시 압축 해제를 하기 때문에 오버헤드가 발생합니다.

 

3. 유니티 음원 출력을 위한 컴포넌트 AudioSource

게임을 만들다 보면 게임의 흐름을 관리하는 게임 매니저가 필요하다는 것을 알게 됩니다. 이와 함께 BGM과 효과음의 음원을 적절하게 사용할 수 있도록 해주는 사운드 매니저 또는 오디오 매니저가 필요하게 됩니다. 사운드 매니저를 만들어 사용하기 전에 유니티에서 사운드 출력에 필요한 AudioSource 컴포넌트에 대해 알아보겠습니다.

- AudioClip 재생할 오디오 파일을 할당합니다. 여기에 Sounds 폴더에 있는 음원 파일을 드래그 앤 드롭합니다.

- Output 오디오 클립을 오디오 믹서로 출력하도록 합니다. 오디오 믹서는 나중에 다루겠습니다.

- Mute 음소거

- Play on Awake 게임 시작 시 오디오 재생

- Loop 오디오 반복 재생

- Volume 오디오 볼륨 조절

- 3D Sound Settings 음향의 다각화 입체적 출력을 세팅

 

4. 사운드 출력 방식

유니티에서 사운드 출력은 AudioSource 컴포넌트에 접근하면 AudioClip을 재생(Play)할 수 있습니다.

public class PlaySound : MonoBehaviour
{
  public AudioSource bgmplayer = null;

  public void PlayBGM()
    {
          bgmplayer.Play();
    }
}

위 스크립트와 같이 사운드 재생은 매우 간단합니다. 소리가 출력되는 오브젝트에 audioSource 컴포넌트가 존재하고 해당 컴포넌트에 이를 제어하는 스크립트(위 예제 PlaySound)를 통해서 음원을 출력합니다. 음원의 출력 방법은 스크립트를 만들기에 따라 다르지만 대체적으로 오브젝트에서 개별적으로 출력하는 방법과 사운드 매니저를 통해서 통합 제어하는 방법이 있습니다.

첫번째 방법은 다수의 오브젝트에 각각의 audioSource를 추가하고 이벤트에서 따라서 audioclip이 재생되는 방식입니다. 이 방식은 각각의 오브젝트에서 이벤트가 발생할 때 즉시 해당 위치에서 audio를 재생하는 방식입니다. 이벤트가 순차적으로 발생하면 문제가 없겠지만 동시 다발적으로 발생하면 음이 겹치는 문제가 발생하게 됩니다. 뿐만 아니라 null reference exception 에러를 발생시킬 수도 있습니다. 예를 들어 오크 유닛 오브젝트가 있는데 오크가 죽을 때 'ordDeadSound'의 audioClip을 audioSource를 통해서 재생하려고 합니다. 그러나 오크 유닛이 죽으면 해당 오브젝트를 SetActive(false)로 비활성화 하거나 Destroy(gameobject)로 제거하는데 이때 오크의 죽는 효과음을 재생하기 위해서 오브젝트에 있는 스크립트가 audioSource에 접근을 시도하는데 이미 오브젝트는 없는 상태가 되니 문제가 발생하게 됩니다. 물론 이 문제는 앞서 알아본 코루틴을 통해서 해결은 가능하지만 사운드의 출력에는 다른 방법이 있기 때문에 다른 방법을 알아보겠습니다.

두번째 방법은 사운드 매니저를 통해서 다수의 오브젝트에서 발생하는 음원의 출력을 재생하는 방법입니다. 다만 이 방법은 동시다발적으로 발생하더라도 가장 먼저 재생되는 음원 하나로 듣게 됩니다. 예를 들어 스타크래프트의 많은 병력을 동시에 클릭할 때 일일히 모든 오브젝트에서 효과음을 발생시키지는 않습니다. 한 개의 상위 유닛이 이를 대표하기 때문입니다. 사운드 매니저는 다량의 효과음을 통합해서 관리하고 씬의 전환에서 BGM을 교체하는데 좋은 컴포넌트가 됩니다.

 

5. SoundManager or AudioManager with Singleton

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

[System.Serializable]
public class Sounds
{
    public string name;
    public AudioClip clip;
}

public class SoundManager : SingletonBehaviour<SoundManager>
{
    [SerializeField] 
    Sounds[] sfx = null;
    [SerializeField] 
    Sounds[] bgm = null;

    [SerializeField] AudioSource bgmplayer = null;
    [SerializeField] AudioSource[] sfxplayer = null;

    public void PlayBGM(string bgms)
    {
        for (int i = 0; i < bgm.Length; i++)
        {
            if(bgms == bgm[i].name)
            {
                bgmplayer.clip = bgm[i].clip;
                bgmplayer.Play();
            }
        }
    }

    public void StopBGM()
    {
        bgmplayer.Stop();
    }

    public void PlaySFX (string _sfx)
    {
        for (int i = 0;i < sfx.Length;i++)
        {
            if(_sfx == sfx[i].name)
            {
                for(int j = 0;j < sfxplayer.Length;j++)
                {
                    if (!sfxplayer[j].isPlaying)
                    {
                        sfxplayer[j].clip = sfx[i].clip;
                        sfxplayer[j].Play();
                        return;
                    }
                }
                return;
            }
        }
        return;
    }

위 스크립트는 앞서 알아본 싱글톤 패턴이 사용된 사운드 매니저 입니다. 따라서 이 스크립트는 씬이 전환되어도 최초의 인스턴스는 파괴되지 않고 단 한개만으로 게임의 시작부터 끝까지 BGM과 SFX 음원을 관리하게 됩니다. Sounds라는 클래스를 먼저 만들고, [System.Serializable] 통해서 Inspector에서 접근 가능하도록 합니다. Sounds[] sfx, Sounds[] bgm은 한 개의 음원이 아닌 여러개의 음원을 관리하기 위해서 배열의 변수를 선언하고, 이를 Inspector에서 관리합니다. BGM이나 SFX 모두 Length로 생성된 만큼 bgmplayer.clip이나 sfxplayer[j].clip을 각각의 Play(); 를 통해서 음원을 재생할 수 있습니다. 해당 음원들의 지정은 각 함수의 string타입 인자를 통해서 할당받게 됩니다. 이 문자열(string)은 SoundManager가 있는 오브젝트의 Inspector에서 문자열 키값을 지정할 수 있습니다. 이 문자열은 이벤트가 발생하는 함수에서 사용되며 이벤트 발생 시 사운드 매니저 인스턴스에 있는 PlayBGM(string bgms) 또는 PlaySFX (string _sfx) 함수를 호출해서 원하는 음원을 재생하게 됩니다. 따라서 해당 문자는 정확히 일치해야 합니다.

string 타입으로 SoundManager Instance에 있는 PlaySFX 함수를 호출

위 그림을 보면 우측 그림에서 OnTriggerEnter2D를 통해서 Wall이라는 태그가 있는 오브젝트에 충돌 시 사운드매니저 인스턴스에 있는 PlaySFX를 호출하게 되는데 이때 Collision 문자값을 인자로 전달합니다. 이를 전달 받은 사운드매지너는 좌측 그림에서 Name 부분이 Collison과 일치하는 것을 For루프를 돌면서 찾고 일치한 부분의 할당된 audioClip을 재생하게 됩니다.

싱글톤 패턴의 스크립트는 자체적으로 인스턴스를 갖게 되기 때문에 다른 클래스나 스크립트에서도 접근이 가능합니다. 위 그림과 같이 싱글톤의 SoundManager 클래스를 어느 스크립트에서도 Instance를 통해 사용 가능합니다. 이런 사운드 매니저 또는 오디오 매니저를 사용하면 AudioSource 컴포넌트를 지닌 오브젝트가 파괴된다 하더라도 참조할 사운드 매지너의 오브젝트는 별도로 존재하기 때문에 음원 재생 시 null reference exception 에러가 발생하지 않습니다. 사운드 매니저에서 원하는 BGM이나 SFX만큼 배열을 늘린 후에 적절한 음원(clip)을 할당하고 SoundManager.Instance를 사용하면 편리하게 게임 제작에 필요한 음원 재생을 할 수 있습니다. 다음은 씬 전환을 부드럽게 하는 방법과 게임에서 발생하는 UI를 재미있게 처리하는 트위닝에 대해서 알아보겠습니다.