이전에 싱글톤 관련 글을 정리하면서 마지막에 한번 언급했던 내용을 다뤄보겠습니다!
https://welcomeheesuk.tistory.com/62
유니티로 게임을 개발하다보면 Sington패턴으로 정보들을 관리하면 좋을때가 많습니다.
그러면서 MonoBehaviour를 상속받는데 싱글톤처럼 동작하도록 구현하고 싶을때가 있습니다.
그럴때 사용하면 좋은것이 바로 '모노싱글톤(MonoSingleton)'입니다.
이 싱글톤이야말로 유니티 관련 싱글톤을 검색하면 흔히 볼 수 있는 싱글톤입니다.
대표적으로 사운드매니저, 오디오 매니저가 있습니다.
AudioSource 컴포넌트를 들고있어야 하지만 싱글톤 처럼 하나만 존재하면 정말 좋을 것 같은 기능입니다.
우선 MonoSingleton부터 살펴보겠습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static object lockObject = new object();
private static T instance = null;
private static bool IsQuitting = false;
public static T Instance
{
// 쓰래드 안전화 - Thread-Safe
get
{
// 한번에 한 스래드만 lock블럭 실행
lock (lockObject)
{
// 비활성화 됐다면 기존꺼 내비두고 새로 만든다.
if ( IsQuitting )
{
return null;
}
// instance가 NULL일때 새로 생성한다.
if (instance == null )
{
instance = GameObject.Instantiate(Resources.Load<T>("MonoSingleton/" + typeof(T).Name));
DontDestroyOnLoad(instance.gameObject);
}
return instance;
}
}
}
private void OnDisable()
{
// 비활성화 된다면 null로 변경
IsQuitting = true;
instance = null;
}
}
보시면 느껴지시겠지만 Resources/MonoSingleton 폴더에 있는 Prefab을 Instantiate해서 하이라키상에 유지시키는 방법입니다. 다양한 여러 방식이 있지만 해당 방법이 가장 알아보기도 쉽고 관리하기도 쉬운 방법이라고 생각했습니다.
모든 MonoSingleton관련된 프리팹은 해당 폴더에 전부 모여있어 관리하거나 변경사항이 있을때 쉽게 접근이 가능할 것 같습니다.
다음은 MonoSingleton을 상속 받는 AudioManager입니다.
using UnityEngine;
public enum SFX
{
BUTTON,
}
public enum BGM
{
OUTGAME,
}
public class AudioManager : MonoSingleton<AudioManager>
{
[SerializeField]
private AudioSource sfxSource = null;
[SerializeField]
private AudioSource bgmSource = null;
[SerializeField]
private AudioClip[] sfxList = {};
[SerializeField]
private AudioClip[] bgmList = {};
private void Awake()
{
// 사운드 초기화
this.sfxSource.loop = false;
this.bgmSource.loop = true;
}
public static void PlayBgm(BGM _bgmType)
{
int bgmType = (int)_bgmType;
Instance.bgmSource.clip = Instance.bgmList[bgmType];
Instance.bgmSource.Play();
}
public static void PlaySfx(SFX _sfxType, float _distance = 4f)
{
int sfxNumber = (int)_sfxType;
Instance.sfxSource.PlayOneShot(Instance.sfxList[sfxNumber], Instance.sfxSource.volume);
}
public static void StopSfx()
{
Instance.sfxSource.Stop();
}
public static void StopBgm()
{
Instance.bgmSource.Stop();
}
public static void SetMuteSfx(bool _mute)
{
Instance.sfxSource.mute = _mute;
}
public static void SetMuteBgm(bool _mute)
{
Instance.bgmSource.mute =_mute;
}
public static void ChangeSfxVolume(float _value)
{
Instance.sfxSource.volume = _value;
}
public static void ChangeBgmVolume(float _value)
{
Instance.bgmSource.volume = _value;
}
public static float GetVolumeSfx()
{
return Instance.sfxSource.volume;
}
public static float GetVolumeBgm()
{
return Instance.bgmSource.volume;
}
public static bool GetMuteSfx()
{
return Instance.sfxSource.mute;
}
public static bool GetMuteBgm()
{
return Instance.bgmSource.mute;
}
}
메소드들은 bgm과 sfx들을 켜고 끄는 기능들이 있습니다.
다음은 실행부입니다. 별거 없이 그냥 audiomanager에 있는 메소드를 한번 호출해줍시다.
singleton의 가장 강한 기능인 호출안하면 생성안하면 한번 호출하고나서부터는 이것만 쓴다를 따릅니다.
public class OutgameUI : MonoBehaviour
{
// 리소스가 없어 그냥 Instance만 하도록 해봤습니다.
void Start()
{
AudioManager.StopBgm();
}
}
당연하지만 씬을 옮기게 되도 파괴되지않고 계속 유지됩니다.
이렇게 데이터 연산에만 필요한 일반 싱글톤에 이어
MonoBehaviour을 이용해야만 하는데 싱글톤 기능을 하는 모노싱글톤까지 살펴봤습니다.
싱글톤만 잘 관리하고, 역할 분리만 잘 해줘도 경험상 행복하게 유지보수 할 수 있는 개발에 다가갈 수 있는것 같습니다!
'게임 개발 > Unity' 카테고리의 다른 글
[유니티 firebase] - 파이어베이스 시작하기 (0) | 2023.05.08 |
---|---|
[유니티 C#] 특정 텍스트 눌러서 팝업 띄우기 (2) | 2022.08.29 |
[유니티 C#] SafeArea 상,하,좌,우 4방향 각자 대응 (0) | 2021.07.24 |
[유니티 C#] UI Animation State 이름 중복 사용 (0) | 2021.07.11 |
[유니티 C#] PhotonNetwork 기본 콜백함수 찍먹하기 (1) | 2021.06.09 |