
Where Am I?8일차에는 자잘한 기능을 마무리하고 실제로 빌드를 해서 생기는 버그, 에러, 피드백을 수정하는 시간을 가졌다. 실제 빌드 테스트를 위해 친구에게 부탁을 했는데 공포 게임을 많이 무서워해서 인게임 피드백보다는 버그 위주 수정이 이루어졌다. 그래도 시간을 내줘서 너무 고마웠다.
작업한 내역은 다음과 같다.
이번에 소개할 코드는 Setting, 환경설정이다. 환경설정은 7일차에 작업한 내용이지만, 설정 값을 인게임에 적용시키는 방법과 유지하기 위해 꽤나 고민했기에 한 번 정리해야 할 필요가 있을 것 같다.
SettingManagerSettingManager는 설정 값을 저장하고 불러오는 Class로 전역적인 접근을 위해 Singleton 패턴을 사용하고, 값을 유지하기 위해 DontDestroyOnLoad 처리를 하여 이름만 Manager일 뿐 Setting Property라고 생각하면 된다.
public class SettingManager : Singleton<SettingManager>
{
// 순서대로 밝기, 시야각, 음량, 마우스 민감도 값을 저장하기 위한 Property
public Property<float> Brightness;
public Property<float> FOV;
public Property<float> Sound;
public Property<float> MouseSpeed;
// Singleton 초기화 메서드, DontDestroyOnLoad, 각 Property 초기화
protected override void Awake()
{
base.Awake();
if (transform.parent == null)
{
DontDestroyOnLoad(gameObject);
}
Init();
}
// Property 초기화 메서드
private void Init()
{
Brightness = new Property<float>(0.5f);
FOV = new Property<float>(0.5f);
Sound = new Property<float>(0.5f);
MouseSpeed = new Property<float>(0.5f);
}
// 외부(UI)에서 값을 변경하기 위해 Property별로 구독되는 메서드
public void SetBrightness(float input)
{
Brightness.Value = input;
}
public void SetFOV(float input)
{
FOV.Value = input;
}
public void SetSound(float input)
{
Sound.Value = input;
}
public void SetMouseSpeed(float input)
{
MouseSpeed.Value = input;
}
}
SettingUIpublic class SettingUI : MonoBehaviour
{
// 각 설정 값을 조절하는 Slider들
[SerializeField] private Slider _lightSlider;
[SerializeField] private Slider _fovSlider;
[SerializeField] private Slider _soundSlider;
[SerializeField] private Slider _mouseSlider;
// 저장, 취소 버튼
[SerializeField] private Button _saveButton;
[SerializeField] private Button _exitButton;
// 설정을 취소할 때 되돌리기 위한 기존 설정 값을 저장하는 필드
private float _cacheBrightness;
private float _cacheFOV;
private float _cacheSound;
private float _cacheMouseSpeed;
private void Start()
{
// 각 Slider와 SettingManager의 Property를 연결
_lightSlider.onValueChanged.AddListener((value)=> SettingManager.Instance.SetBrightness(value));
_fovSlider.onValueChanged.AddListener((value)=> SettingManager.Instance.SetFOV(value));
_soundSlider.onValueChanged.AddListener((value)=> SettingManager.Instance.SetSound(value));
_mouseSlider.onValueChanged.AddListener((value)=> SettingManager.Instance.SetMouseSpeed(value));
// 각 버튼에 해당하는 메서드 구독
_saveButton.onClick.AddListener(() => SettingSave());
_exitButton.onClick.AddListener(()=>
{
SettingUpdate();
gameObject.SetActive(false);
});
CacheInit();
SettingUpdate();
gameObject.SetActive(false);
}
// SettingManager에 저장된 각 Property 값을 필드에 저장(초기화)
private void CacheInit()
{
_cacheBrightness = SettingManager.Instance.Brightness.Value;
_cacheFOV = SettingManager.Instance.FOV.Value;
_cacheSound = SettingManager.Instance.Sound.Value;
_cacheMouseSpeed = SettingManager.Instance.MouseSpeed.Value;
}
// 필드에 저장된 값으로 SettingManager 업데이트(설정 되돌리기 담당 메서드)
private void SettingUpdate()
{
SettingManager.Instance.SetBrightness(_cacheBrightness);
SettingManager.Instance.SetFOV(_cacheFOV);
SettingManager.Instance.SetSound(_cacheSound);
SettingManager.Instance.SetMouseSpeed(_cacheMouseSpeed);
// Slider 값 복구
_lightSlider.value = _cacheBrightness;
_fovSlider.value = _cacheFOV;
_soundSlider.value = _cacheSound;
_mouseSlider.value = _cacheMouseSpeed;
}
private void SettingSave()
{
// Slider 값으로 필드 값 업데이트
_cacheBrightness = _lightSlider.value;
_cacheFOV = _fovSlider.value;
_cacheSound = _soundSlider.value;
_cacheMouseSpeed = _mouseSlider.value;
}
}
실제로 값이 변경되었을 경우 해당 값을 인게임에 구현하는 방법이다.
public class PlayerCam : MonoBehaviour
{
private void Start()
{
// 설정 값으로 초기화
FOVUpdate(SettingManager.Instance.FOV.Value);
MouseSpeedUpdate(SettingManager.Instance.MouseSpeed.Value);
// Property 이벤트 메서드 구독
SettingManager.Instance.FOV.OnChanged += FOVUpdate;
SettingManager.Instance.MouseSpeed.OnChanged += MouseSpeedUpdate;
}
private void OnDestroy()
{
// Destroy될 경우 구독 해제
SettingManager.Instance.FOV.OnChanged -= FOVUpdate;
SettingManager.Instance.MouseSpeed.OnChanged -= MouseSpeedUpdate;
}
// 시야각 설정 값 반영
private void FOVUpdate(float value)
{
float fov = Mathf.Lerp(50, 70, value);
_playerCam.fieldOfView = fov;
}
// 마우스 민감도 설정 값 반영
private void MouseSpeedUpdate(float value)
{
float speed = Mathf.Lerp(0.2f, 5, value);
_rotateSpeed = speed;
}
}