주어진 에셋이 매우 귀여워서 놀랐다.
공포게임인줄 알았는데 캐릭터 디자인만 보면 힐링 게임이다.
매니저들이 만들어질 메인메뉴부터 만들기로 했다.
첫인상이 중요하니깐 얼추 꾸며 놓고
GameManager, SoundManager와 메인메뉴 버튼을 관리할 MainMenuManager를 만들고 스크립트를 짰다
GameManager는 아직 특별한게 없다.
SoundManager에서 뻘짓을 조금 했는데
바꾸기전 코드에서는 이전 과제에서 해왔던 것 처럼 SoundManager가 모든 클립과 소스를 다 갖고 다른 오브젝트가 Manager의 함수를 호출하는 방식으로 짰었다 아래는 바꾸기전 코드
using System.Collections;
using System.Collections.Generic;
using System.Data;
using UnityEngine;
public class SoundManager : MonoBehaviour
{
public static SoundManager instance;
[SerializeField] private AudioClip SFXBuzzingLight;
[SerializeField] private AudioClip SFXCandle;
[SerializeField] private AudioClip SFXFootstepsLooping;
[SerializeField] private AudioClip SFXGameOver;
[SerializeField] private AudioClip SFXGhostMove;
[SerializeField] private AudioClip SFXHouseAmbience;
[SerializeField] private AudioClip SFXWin;
private Dictionary<string, AudioSource> audioSources = new Dictionary<string, AudioSource>();
void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject);
}
else if (instance != this)
{
Destroy(gameObject);
}
}
void Start()
{
AudioSource[] sources = GetComponents<AudioSource>();
foreach (AudioSource source in sources)
{
audioSources.Add(source.clip.name, source);
}
}
public void PlaySound(string clipName)
{
if (audioSources.ContainsKey(clipName))
{
audioSources[clipName].Play();
}
}
public void SetSoundVolume(string clipName, float volume)
{
if (audioSources.ContainsKey(clipName))
{
audioSources[clipName].volume = volume;
}
}
public void SettingSFXSoundVolume(float volume)
{
foreach (KeyValuePair<string, AudioSource> audioSource in audioSources)
{
if (audioSource.Key == SFXHouseAmbience.name)
continue;
audioSource.Value.volume = volume;
}
}
public void SettingAmbienceSoundVolume(float volume)
{
if (audioSources.ContainsKey(SFXHouseAmbience.name))
{
audioSources[SFXHouseAmbience.name].volume = volume;
}
}
}
열심히 짜다 보니깐 이 게임은 3D이고 소스가 SoundManager에 있으면 소리나는 위치가 항상 동일하게 날 것이고 이러면 부자연스럽다.
대안으로 생각해낸게 모든 사운드 소스를 분산시키는 거고 그럼 SoundManager에서 volume setting을 할 수 없게 된다.
검색을 하여 AudioMixer를 도입해 해결했다.
원래는 Audio source -> Listener 흐름이라면 Audio source -> Mixer -> Listener 로 중간다리를 놓는 것
오브젝트에 소스를 넣고 output설정을 Mixer로 놓으면 Mixer만 설정하면 볼륨조절 뿐만 아니라 사운드 관련 설정들을 한방에 관리할 수가 있었다.
그래서 바뀐 코드
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using UnityEngine;
using UnityEngine.Audio;
public class SoundManager : MonoBehaviour
{
public static SoundManager instance;
[SerializeField] private AudioMixer audioMixer;
void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(gameObject);
}
else if (instance != this)
{
Destroy(gameObject);
}
}
void Start()
{
SetBGMVolume(PlayerPrefs.GetFloat("BGMVolume", 0));
SetSFXVolume(PlayerPrefs.GetFloat("SFXVolume", 0));
}
public void SetSFXVolume(float volume)
{
if (volume <= 0.0001f)
audioMixer.SetFloat("SFX", -80);
else
audioMixer.SetFloat("SFX", Mathf.Log10(volume) * 20);
}
public void SetBGMVolume(float volume)
{
if (volume <= 0.0001f)
audioMixer.SetFloat("BGM", -80);
else
audioMixer.SetFloat("BGM", Mathf.Log10(volume) * 20);
}
}
AudioMixer의 볼륨은 단위가 dB이라서 볼륨 조정할 Slider의 float (0, 1) 과 달라 계산식을 넣어주었고
volume == 0 이면 계산식이 -Infinite가 되어 볼륨이 다시 커지는 버그를 발견하여 0되기 전에 볼륨을 꺼주었다.
확실히 코드가 깔끔해지고 사운드 추가할때마다 SoundManager에 넣어주고 소스 만들고 하는 것보다 훨씬 좋다
지금까지 결과물
정리하다보니 SoundManager보다 AudioManager가 좋을거 같아서 변경!
이제 플레이어 이동 구현 해야지
'Unity > John Lemon in Nightmareland' 카테고리의 다른 글
Unity Piscine Module06 - 6. 맵 구현 (0) | 2024.08.26 |
---|---|
Unity Piscine Module06 - 5. FPS / TPS 시점 적용 (0) | 2024.08.25 |
Unity Piscine Module06 - 4. 움직임 구현 (0) | 2024.08.22 |
Unity Piscine Module06 - 2. 구조 설정 (0) | 2024.08.21 |
Unity Piscine Module06 - 1. 과제 해석 (1) | 2024.08.21 |