섹션9. Sound
위 글은 인프런에 있는 Rookiss님의 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진 강의를 듣고 남긴 필기입니다.
[사운드를 들을 때 필요한 것]
- 소리의 근원지 (음향 송신) :
AudioSource
- 소리 :
AudioClip
- 귀 (음향 수신) :
AudioListener
→ 기본 MainCamera에 부착되어 있음.
AudioSource 컴포넌트
SoundManager
Sound
를 담당하는SoundManager
를 만듦.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
public class SoundManager
{
private AudioSource[] _audioSources = new AudioSource[(int)Define.Sound.MaxCount];
// AudioClip Caching을 담당하는 Dictionary
private Dictionary<string, AudioClip> _audioClips = new Dictionary<string, AudioClip>();
// [사운드를 들을 때 필요한 것]
// 소리의 근원지 (음향 송신) : AudioSource
// 소리 : AudioClip
// 귀 (음향 수신) : 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++) // Define.Sound.MaxCount는 제외
{
GameObject go = new GameObject { name = soundNames[i] };
_audioSources[i] = go.AddComponent<AudioSource>();
go.transform.parent = root.transform;
}
_audioSources[(int)Define.Sound.Bgm].loop = true; // BGM은 Loop : true
}
}
/// <summary>
/// 오디오 플레이 함수. string 버전
/// </summary>
/// <param name="path">음원 파일 경로</param>
/// <param name="type">어떤 형태의 음원인지</param>
/// <param name="pitch"></param>
public void Play(string path, Define.Sound type = Define.Sound.Effect, float pitch = 1.0f)
{
var audioClip = GetOrAddAudioClip(path, type);
Play(audioClip, type,pitch);
}
/// <summary>
/// 오디오 플레이 함수. AudioClip 버전
/// </summary>
/// <param name="audioClip">음원 AudioClip</param>
/// <param name="type">어떤 형태의 음원인지</param>
/// <param name="pitch"></param>
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);
}
}
/// <summary>
/// AudioClip을 불러올 때 활용. AudioClip Caching 함수.
/// </summary>
/// <param name="path">AudioClip 파일 경로</param>
/// <returns></returns>
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) // BGM일 때
{
audioClip = Managers.Resource.Load<AudioClip>(path);
}
else // Effect일 때
{
if (_audioClips.TryGetValue(path, out audioClip) == false) // 조건부 Caching
{
audioClip = Managers.Resource.Load<AudioClip>(path);
_audioClips.Add(path,audioClip);
}
}
if (audioClip == null)
Debug.Log($"AudioClip is Missing! {path}");
return audioClip;
}
/// <summary>
/// AudioClip Cache Clear 함수.
/// </summary>
public void Clear()
{
foreach (var audioSource in _audioSources)
{
audioSource.clip = null;
audioSource.Stop();
}
_audioClips.Clear();
}
}
- Sound의 종류를 구분하기 위해
Utils > Define.cs
에 다음과 같은 enum을 생성
1
2
3
4
5
6
public enum Sound
{
Bgm,
Effect,
MaxCount,
}
- Managers 클래스에 다음의 함수를 추가
1
2
3
4
5
6
7
8
9
10
/// <summary>
/// Scene을 이동할 때 호출해야 하는 함수.
/// </summary>
public static void Clear()
{
Sound.Clear(); // Caching된 AudioClip들을 비우는 함수
Input.Clear(); // KeyAction과 MouseAction을 비우는 함수
UI.Clear(); // 모든 Popup과 SceneUI를 비우는 함수
Scene.Clear(); // 현재 Scene클래스(BaseScene을 상속하는 클래스)의 Clear()를 호출하는 함수
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.