Effect의 경우, 같은 effect를 여러 번 불러오게 되면, 불러올 때마다 manager를 호출하는 게 부하를 줄 수 있으므로 캐싱을 해둔다
public class SoundManager
{
Dictionary<string, AudioClip> _audioClips = new Dictionary<srting, AudioClip>();
public void Init()
{
// Init
}
// Scene 이동 시 캐싱된 audio source&clip 초기화
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)
{
if (type == Define.Sound.Bgm)
{
// BGM 실행
}
else
{
AudioClip audioClip = GetOrAddAudioClip(path);
if (audioClip == null)
{
Debug.Log($"AudioClip Missing : {path}");
return;
}
AudioSource audioSource = _audioSources[(int)Define.Sound.Effect];
audioSource.pitch = pitch;
audioSource.clip = audioClip;
audioSource.PlayOneShot(audioClip);
}
}
// 이전에 불러왔던 clip을 캐싱
AudioClip GetOrAddAudioClip(string path)
{
AudioClip audioClip = null;
if (_audioClips.TryGetValue(path, out audioClip) == false)
{
audioClip = Managers.Resource.Load<AudioClip>(path);\
_audioClips.Add(path, audioClip);
}
return audioClip;
}
}
Managers.cs에서 Scene이 이동할 때마다 데이터들을 날려주기 위한 Clear 함수를 추가한다
public static void Clear()
{
Input.Clear();
Sound.Clear();
Scene.Clear();
UI.Clear();
}
InputManager에서도 초기화를 위한 Clear 함수를 만들어준다
public void Clear()
{
// Action 선언해두었던 것들 초기화
KeyAction = null;
MouseAction = null;
}
그리고 씬이 바뀔 때 초기화를 해주기 위하여 SceneManagerEx 스크립트에서도 아래와 같이 수정해준다
public class SceneManagerEx
{
public void LoadScene(Define.Scene type)
{
Managers.Clear();
SceneManager.LoadScene(GetSceneName(type));
}
string GetSceneName(Define.Scene type)
{
// Scene Manager 참고
}
public void Clear()
{
CurrentScene.Clear();
}
}
UI Manager에서도 pop stack 등을 초기화시켜준다
public void Clear()
{
CloseAllPopupUI();
_sceneUI = null;
}
Sound Manager에서 새로운 함수(clip을 직접 받는 버전)를 추가해주면서, 함수를 기능 단위로 나눠준다
// 기존
public void Play(string path, Define.Sound type = Define.Sound.Effect, float pitch = 1.0f)
{
AudioClip audioClip = GetOrAddAudioClip(path, type);
Play(audioClip, type, pitch);
}
// Clip을 직접 받음
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;
}
+
PlayClipAtPoint(): 지정한 클립을 특정 위치에서 재생할 수 있게 하는 함수
'강의, 책 > [Unity] C#과 유니티로 만드는 MMORPG 게임 개발 시리즈' 카테고리의 다른 글
Section 11. Coroutine (0) | 2024.02.03 |
---|---|
Section 10. Object Pooling - Pool Manager (0) | 2024.02.03 |
Section 9. Sound - Sound Manager(1) (0) | 2024.02.02 |
Section 8. Scene - Scene Manager (0) | 2024.01.31 |
Section 7. UI - 코드 정리 (0) | 2024.01.31 |