SoundManager

개발조하·2024년 1월 2일
0

Unity

목록 보기
20/30
post-thumbnail

1. Sound 필수 요소

내용Unity 컴포넌트사용 방법
MP3 PlayerAudioSource오브젝트에 컴포넌트 추가
MP3 음원AudioClip오브젝트에 컴포넌트 추가
관객(귀)AudioListenerMainCamera에 기본 부착되어있음

Audiosource

Game씬의 Cube2에 Audiosource 컴포넌트를 추가했다.

💡 AudioSource 프로퍼티

AudioListener

AudioListener는 Main Camera에 디폴트로 붙어있다.

만약 거리에 따른 현실감을 부여하고 싶다면 Player에 AudioListener컴포넌트를 추가하고, MainCamera에 있는 컴포넌트는 비활성화해주면 된다!

2. Sound 실행

TestSound를 Cube2에 붙이고 인스펙터에서 AudioClip을 지정해준다.
위에 코드를 살펴보면 현재 audioClip 두 개가 모두 실행되도록 되어있다. 이처럼 유니티에서는 여러 개의 AudioClip을 동시에 출력할 수 있다.
즉, 하나의 AudioSource에 꼭 한 개의 AudioClip만 재생할 수 있는 것은 아니다.

💡 만약, 사운드가 출력 중인 오브젝트를 Destroy 하면?
-> 0.25초 후에 사운드도 함께 사라지게 된다.
-> 2개의 오디오 클립 중 길이가 더 긴 클립을 기준으로 오브젝트를 파괴시켜서 모든 사운드가 다 출력될 수 있도록 했다.

하지만, 이렇게 Audio를 기준으로 오브젝트를 파괴하는 로직이 합당하지는 않다.
오브젝트가 먼저 파괴되면 audio가 끊겨버리는 문제가 발생하고, audio에 맞추기에는 게임 중 오브젝트의 애니메이션이나 기타 효과 및 기능이 있을 수 있기 때문이다.
이에 AudioSource를 오브젝트에 부착하는 것이 아니라 SoundManager에 부착하여 관리하는 것이 더욱 용이하다.

2. SoundManager.cs 생성

사운드를 관리할 SoundManager.cs를 생성하고, Managers에 등록한다.

먼저, Sound의 종류를 분류해주기 위해 Define.cs에 Sound 종류를 정의한다.

SoundManager.cs에 Init()과 Play()를 만들어준다.

  • Init() : @Sound 오브젝트 생성 + AudioSource 컴포넌트 부착 / Bgm의 경우 loop 활성화

  • Play() : 재생 시 type에 따른 AudioClip 재생

Managers.cs에 SoundManager.Init() 코드 추가

사운드가 필요한 부분에 코드 작성

3. 캐싱

Bgm의 경우에는 어쩌다 한 번씩 AudioClip이 변경될테지만, Effect의 경우에는 쉴 새 없이 AudioClip이 필요하다. 이때마다 AudioClip audioClip = Managers.Resource.Load<AudioClip>(path);으로 audioClip을 가져오면 부하가 생길 수 있다. 이를 방지하기 위해 캐싱이 필요하다.

즉, 한 번 사용된 audioClip은 딕셔너리에 저장해뒀다가 다시 사용하고, 딕셔너리에 없는 audioClip만 Resource경로에서 찾아서 가져온다.

4. Clear()로 메모리 관리

SoundManager.cs에 Clear() 추가

ㄴ 씬이 변경되는 등의 상황에 Clear()를 호출하여 캐시를 싹 삭제시켜 혹시 모를 메모리 낭비를 방지한다.

Sound외에도 InputManager와 SceneManager, UIManager에서도 씬이 변경될 때마다 메모리를 처리하여 메모리 낭비를 방지한다.

5. 3D Sound 효과 (거리감)

6. Play() 2가지 버전으로 분리

6.1 audioClip을 매개변수로 받는 버전 추가

현재 사용하고 있는 public void Play(string path, Define.Sound type = Define.Sound.Effect, float pitch = 1.0f)는 string path로 경로를 받아서 audioClip을 불러오고 있다. 나중에 데이터베이스를 활용하여 Json, XML로 사용할 때는 문제가 없겠지만 지금의 경우에는 계속 이렇게 path로 불러오는 것이 비효율적이기 때문에 직접 audioClip을 매개변수로 받아오는 Play()를 별도로 만들어주자.

6.2 2가지 버전 중복 코드 정리

두가지 버전은 audioClip을 지정해주는 방식만 다를 뿐, audioSource에 해당 audioClip을 재생하는 코드는 똑같다.

즉, AudioClip을 직접 받는 버전의 Play()로 항상 재생하는 코드를 실행할 수 있다.

  • AudioClip 지정하기
    캐싱을 위해 만들었던 AudioClip GetOrAddAudioClip(string path)코드를 가공하여 아예 audioClip을 찾아주는 메서드로 만들자.
    이로써 path에 따른 audioClip을 찾았다.

  • 재생하기
    찾은 audioClip으로 재생을 실행한다.

-> 전체 코드

📄참고자료
[인프런] c#과 유니티로 만드는 MMORPG 게임 개발 시리즈_3. 유니티 엔진
Unity Documentation_Audiosource

profile
Unity 개발자 취준생의 개발로그, Slow and steady wins the race !

0개의 댓글