
프로젝트 개요
- Unity에서 사운드 에셋 관리를 쉽게 도와주는 패키지
- CategorizedDB 하위 프로젝트
- Owner & Maintainer : 홍기표(Postive)
- 도구 : Unity, C#
- Github :
- 시연 영상
이유
- 씬에 AudioSource를 직접 생성하고 사운드, 믹서, 옵션 등을 직접 설정하는 방식으로 소리를 추가하는 게 매우 비효율적이었기에 이를 개선하고 싶었다.
개선 방법
- 사운드 데이터를 저장하고 관리할 에디터를 추가하여 손쉽게 사운드를 추가하고 삭제할 수 있도록 한다. (CategorizedDB) 사용
- SoundManager을 통해 데이터베이스에 저장된 사운드의 정보와 설정 값을 불러와 AudioSource를 생성하고 관리하도록 한다.
기능
- 사운드 에디터 기능
- 소리 에셋을 손쉽게 추가하고 삭제가 가능하며 2D/3D 사운드 설정 또한 가능하다. 3D로 설정될 경우 3D 사운드 관련 옵션이 추가적으로 표시된다.
- 사운드 매니저 기능
- 원하는 SoundData의 GUID를 이용해 SoundManager의 PlaySound 함수를 호출하는 것 만으로 소리를 재생할 수 있다.
기능
- 핵심 기능:
- 사운드 데이터 추가/삭제 기능
- 2D/3D 사운드 설정 기능
- 볼륨 믹서 설정 기능
- 랜덤 사운드, 볼륨, 피치 기능
- SoundManager을 통한 Sound 재생 기능(GUID 기반)
- SoundSelector을 통한 사운드 선택 기능
🆕효과
- 사운드 관리 및 사용 편의성 증가
- 에디터 제공을 통한 기획 혹은 사운드 인력과의 협업 능력 증가
구조
classDiagram
class CategoryElement
class GenericCategorizedDB~T~
class SoundData {
-AudioClip[] _clips
-AudioMixerGroup _mixer
-float _spacialBlend
-bool _useRandomVolume
-float _volume
-Vector2 _volumeRange
-bool _useRandomPitch
-float _pitch
-Vector2 _pitchRange
+AudioClip() Clip
+ClipCount() int
+SpacialBlend() float
+Volume() float
+Pitch() float
+VolumeRange() Vector2
+PitchRange() Vector2
+UseRandomVolume() bool
+UseRandomPitch() bool
+Mixer() AudioMixerGroup
+SpatialSetting() SpatialSetting
}
class SpatialSetting {
+float MinDistance
+float MaxDistance
+float DopplerLevel
+AnimationCurve VolumeRolloff
+AnimationCurve SpatialBlend
+AnimationCurve Spread
+AnimationCurve ReverbZoneMix
}
class SoundDB{
+static Instance() SoundDB
-static SoundDB _instance
}
class SoundManager {
+static SoundManager Instance
+static AudioSource PlaySound(string key, Vector3 position)
+static AudioSource PlaySoundAtTransform(string key, Transform transform)
-static SoundData GetSound(string key)
-static void ApplySoundSettings(AudioSource audioSource, SoundData sound)
-AudioSource GetAudioSource() AudioSource
-AudioSource CreateAudioSource() AudioSource
-void DisableAudioSource(GameObject audioSource, float delay)
-IEnumerator DisableAudioSourceCoroutine(GameObject audioSource, float delay)
-void OnDestroy()
-static SoundManager _instance
-bool _useDebug
-Queue<GameObject> _pooledAudioSources
-AudioListener _audioListener
}
SoundManager *-- SoundData : uses
SoundManager *-- SoundDB : uses
SoundData ..|> CategoryElement
SoundData *-- SpatialSetting : 3D setting
SoundDB --|> GenericCategorizedDB~T~ : T is SoundData
SoundDB *-- SoundData : DataBase data
클래스 설명 및 함수 표 정리
SoundData
- 역할: 개별 사운드 데이터를 정의하는 클래스.
- 상속:
CategoryElement를 상속받아 카테고리 분류 기능 포함. - 주요 기능:
- 여러 오디오 클립을 관리하며, 랜덤으로 선택해 반환 가능.
- 볼륨, 피치, 공간 블렌드 등 사운드 재생 설정 포함.
AudioMixerGroup과 공간 설정(SpatialSetting) 관리.
| 메서드 | 설명 |
getClip() | 오디오 클립 배열에서 무작위로 하나의 클립을 선택해 반환 |
getClipCount() | 오디오 클립 배열의 클립 개수를 반환 |
getSpacialBlend() | 현재 공간 블렌드 비율을 반환 |
setSpacialBlend(float) | 공간 블렌드 비율을 설정 (Editor 전용) |
getVolume() | 랜덤 볼륨이 활성화되었으면 범위 내 무작위 값을 반환, 아니면 기본 값을 반환 |
setVolume(float) | 기본 볼륨 값을 설정 (Editor 전용) |
getPitch() | 랜덤 피치가 활성화되었으면 범위 내 무작위 값을 반환, 아니면 기본 값을 반환 |
setPitch(float) | 기본 피치 값을 설정 (Editor 전용) |
getVolumeRange() | 랜덤 볼륨 범위를 반환 |
setVolumeRange(Vector2) | 랜덤 볼륨 범위를 설정 (Editor 전용) |
getPitchRange() | 랜덤 피치 범위를 반환 |
setPitchRange(Vector2) | 랜덤 피치 범위를 설정 (Editor 전용) |
getUseRandomVolume() | 랜덤 볼륨 사용 여부를 반환 |
getUseRandomPitch() | 랜덤 피치 사용 여부를 반환 |
getMixer() | 현재 오디오 믹서 그룹을 반환 |
SpatialSetting
- 역할: 공간적 사운드 설정을 관리하는 클래스.
- 특징: 사운드의 거리, 도플러 효과, 볼륨 롤오프 등을 설정 가능.
- 주요 기능:
AnimationCurve를 활용해 볼륨 롤오프, 공간 블렌드 등을 커스텀 설정.
| 필드 | 설명 |
MinDistance | 소리가 정상적으로 들리기 시작하는 최소 거리. |
MaxDistance | 소리가 완전히 들리지 않는 최대 거리. |
DopplerLevel | 도플러 효과의 강도를 설정. |
VolumeRolloff | 거리와 볼륨의 관계를 커스텀 설정. |
SpatialBlend | 공간 블렌드 값(2D~3D 전환)을 커스텀 설정. |
Spread | 소리의 방향성 퍼짐 정도를 커스텀 설정. |
ReverbZoneMix | 리버브 존 내에서의 사운드 혼합 정도를 커스텀 설정. |
SoundManager
- 역할: 사운드 재생 및 관리의 중심 역할을 하는 싱글톤 클래스.
- 주요 기능:
- 사운드 데이터를 기반으로 오디오 소스 생성 및 재생.
- 재생 후 오디오 소스를 관리하는 풀링 시스템 제공.
- 공간 및 사운드 설정을 동적으로 적용.
| 함수 | 설명 |
Instance | 싱글톤 패턴으로 SoundManager의 인스턴스를 반환 |
PlaySound(string, Vector3) | 지정된 위치에서 사운드를 재생 |
PlaySoundAtTransform(string, Transform) | 지정된 Transform 위치에 따라 사운드를 재생 |
GetSound(string) | 키를 통해 사운드 데이터를 검색 |
ApplySoundSettings(AudioSource, SoundData) | 오디오 소스에 사운드 데이터를 적용 |
GetAudioSource() | 오디오 소스를 풀링 시스템에서 가져오거나 새로 생성 |
CreateAudioSource() | 새로운 오디오 소스를 생성 |
DisableAudioSource(GameObject, float) | 일정 시간이 지나면 오디오 소스를 비활성화 |
DisableAudioSourceCoroutine(GameObject, float) | 비활성화를 코루틴으로 처리 |
효과
CategorizedDB를 도입하는 것으로 필요한 데이터 클래스를 제작하고 수정하고 관리하는 속도가 빨라졌으며 새로운 데이터베이스를 구성하는 부담이 감소하였다.