Unity 게임 만들기 프로젝트 - SoundManager
1. SoundManager
rpg 게임에서 Sound 역시 중요한 요소 중 하나이다. 크게 Bgm 과 Effect 효과로 구성되고, Sound 를 일일히 관리하기엔 힘드니 Manager 를 통해 관리할 수 있도록 코드를 구성한다.
# SoundManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundManager
{
AudioSource[] _audioSources = new AudioSource[(int)Define.Sound.MaxCount];
Dictionary<string, AudioClip> _audioClips = new Dictionary<string, AudioClip>();
// Mp3 Player -> AudioSource
// Mp3 Music -> AudioClip
// ear -> AudioListener
public void Init()
{
GameObject root = GameObject.Find("@Sound");
if (root == null)
{
root = new GameObject { name = "@Sound" };
Object.DontDestroyOnLoad(root);
string[] soundNames = System.Enum.GetNames(typeof(Define.Sound));
for (int i = 0; i < soundNames.Length - 1; i++)
{
GameObject go = new GameObject { name = soundNames[i] };
_audioSources[i] = go.AddComponent<AudioSource>();
go.transform.parent = root.transform;
}
_audioSources[(int)Define.Sound.Bgm].loop = true;
}
}
public void Clear()
{
foreach (AudioSource audioSource in _audioSources)
{
audioSource.clip = null;
audioSource.Stop();
}
_audioClips.Clear();
}
public void Play(string path, Define.Sound type = Define.Sound.Effect, float pitch = 1.0f)
{
AudioClip audioClip = GetOrAddAudioClip(path, type);
Play(audioClip, type, pitch);
}
public void Play(AudioClip audioClip, Define.Sound type = Define.Sound.Effect, float pitch = 1.0f)
{
if (audioClip == null)
return;
if (type == Define.Sound.Bgm)
{
AudioSource audioSource = _audioSources[(int)Define.Sound.Bgm];
if (audioSource.isPlaying)
audioSource.Stop();
audioSource.pitch = pitch;
audioSource.clip = audioClip;
audioSource.Play();
}
else
{
AudioSource audioSource = _audioSources[(int)Define.Sound.Effect];
audioSource.pitch = pitch;
audioSource.PlayOneShot(audioClip);
}
}
AudioClip GetOrAddAudioClip(string path, Define.Sound type = Define.Sound.Effect)
{
if (path.Contains("Sounds/") == false)
path = $"Sounds/{path}";
AudioClip audioClip = null;
if (type == Define.Sound.Bgm)
audioClip = Managers.Resource.Load<AudioClip>(path);
else
{
if (_audioClips.TryGetValue(path, out audioClip) == false)
{
audioClip = Managers.Resource.Load<AudioClip>(path);
_audioClips.Add(path, audioClip);
}
}
if (audioClip == null)
Debug.Log($"AudioClip Missing ! {path}");
return audioClip;
}
}
AudioSource[] _audioSources : enum 개수만큼 선언했던 AudioSource 에 대한 배열을 선언한다.
Dictionary<string, AudioClip> _audioClips : audioClip 을 관리 할 Dictionary 를 선언한다.
Init 에서는 @Sound 라는 GameObject를 만들고 생성되는 모든 Audio 관련 컴포넌트를 해당 오브젝트 밑에 정리한다.
해당 Scene 에서 @Sound 는 삭제되면 안되기 때문에 DontDestroyOnLoad 에 넣어주고 있다.
각 Enum 에서 선언해준 형식들의 이름을 가진 Gameobject 를 생성한 후 @Sound 의 자식 컴포넌트로 붙여주고 있다.
만약 Bgm 일 경우엔 loop 옵션을 켜서 반복 재생이 되고 있다.
Clear 는 단순히 Scene이 전환될 때 호출하여 불러왔던 audioSource 들을 초기화 해주고 있다.
Play 는 두가지 형식이 있는데, 먼저 audioClip 을 직접적으로 받아서 사용할때의 메소드이다.
audioClip이 지정되어 있지 않다면 return, bgm 이면 Play 를 통해 audioClip을 지정하고 재생해준다.
effect 라면 PlayOneShot 을 통해 한번 수행하는 식으로 수행되게 된다.
직접 지정이 아닌 경로로 되어 있다면 resource 에서 꺼내오게 된다.
GetOrAddAudioClip 를 통해 쉽게 audioClip 을 받아오고, 캐싱하여 자원관리를 할 수 있도록 함수를 구현한다.
불러온 Clip은 이전에 구현했던 Play를 재사용해주고 있다.
GetOrAddAudioClip 은 Sounds 디렉토리 내부에 있는 입력받은 path를 기준으로 AudioClip을 Load 한다.
bgm은 단순히 load하지만 effects 일 때 _audioClips 라는 딕셔너리에 포함되어 있지 않다면 포함시켜 캐시로 활용한다.
'⇥ 2D Game > Unity' 카테고리의 다른 글
Unity 게임 만들기 프로젝트 - DataManager (0) | 2024.06.11 |
---|---|
Unity 게임 만들기 프로젝트 - Coroutine (0) | 2024.06.10 |
Unity 게임 만들기 프로젝트 - SceneManager (0) | 2024.06.10 |
Unity 게임 만들기 프로젝트 - UI Manager, 자동화 (2) | 2024.06.10 |
Unity 게임 만들기 프로젝트 - Camera, Click 이동 구현 (1) | 2024.06.08 |
댓글
이 글 공유하기
다른 글
-
Unity 게임 만들기 프로젝트 - DataManager
Unity 게임 만들기 프로젝트 - DataManager
2024.06.11 -
Unity 게임 만들기 프로젝트 - Coroutine
Unity 게임 만들기 프로젝트 - Coroutine
2024.06.10 -
Unity 게임 만들기 프로젝트 - SceneManager
Unity 게임 만들기 프로젝트 - SceneManager
2024.06.10 -
Unity 게임 만들기 프로젝트 - UI Manager, 자동화
Unity 게임 만들기 프로젝트 - UI Manager, 자동화
2024.06.10