게임 구상을 하느라 시간을 다 썼는데, 마땅한 아이디어가 나오지 않아 큰일이다..
이전 포스팅에서 제네릭 싱글톤에 대해 한 번 다룬 적이 있다.
하지만 왜 써야하는지는 적지 못했고, 해당 코드보다 더 마음에 드는 코드를 발견했다.
우리가 흔히 싱글톤을 구현하는 방법은
public class UIManager : MonoBehaviour
{
private static UIManager instance;
public static UIManager Instance
{
get
{
if(null == instance)
{
return null;
}
return instance;
}
}
private void Awake()
{
if(instance == null)
{
instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
Destroy(this.gameObject);
}
}
public void Save()
{
// 저장 기능
}
}
public class Test : MonoBehaviour
{
void Start()
{
UIManager.Instance.Save();
}
}
그러나 이럴 경우 Static을 쓰면 쓸수록 메모리 누수가 발생한다.
전역 변수와 정적 변수(Static)은 데이터(Data)영역에 저장되는데, 이곳에 저장된 메모리들은 프로그램이 끝날 때 까지 없어지지 않고 계속 남아있기 때문이다.
우리가 매니저를 많이 만들고, Static을 자주 사용할 수록 메모리 낭비가 될 수 있다.
(UIManager, PlayerManager, AudioManager, GameManager...)
매니저마다 싱글톤을 만드는 작업은 굉장히 비효율적이다.
또한 협업을 진행할 경우 싱글톤을 만드는 방법이 다 다르다 보니 차라리 컨벤션을 통해
제네릭으로 싱글톤을 만들어 사용하는 것이다.
이것도 커스텀이 굉장히 많이 되기 때문에, 사용자의 입맛에 따라 수정하길 바람!
using UnityEngine;
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T instance;
public static T Instance
{
get
{
if (instance == null) // 1
{
instance = (T)FindObjectOfType(typeof(T)); // 2
if(instance == null) // 3
{
GameObject obj = new GameObject(typeof(T).Name, typeof(T));
instance = obj.GetComponent<T>();
}
}
return instance;
}
}
public void Awake()
{
if (transform.parent != null && transform.root != null) // 5
{
DontDestroyOnLoad(this.transform.root.gameObject);
}
else
{
DontDestroyOnLoad(this.gameObject); // 4
}
}
}
호출 방법
public class UIManager : Singleton<UIManager>
{
public void Game()
{
Debug.Log("UIManager Singleton");
}
}
public class Test : MonoBehaviour
{
void Start()
{
UIManager.Instance.Game();
}
}
개인 과제 구상 하기!
최종 과제물 아이디어 구상하기!