유니티를 쓰면서 제일 처음 접한 싱글톤은 간단했다.
gameManager에 싱글톤 구현해서 온갖 스크립트에서 참조를 하였다.
물론 규모가 커지니까 수습이 안되서 망했다.
오늘은 이 싱글톤을 정리 해봐야겠다.
#1 그냥 싱글톤
public class gameManager : MonoBehaviour
{
//instance를 static으로 선언해서 다른 오브젝트에서도 접근 가능
public static gameManager instance;
public int enemyLeftAmt; //공유할 아무 변수
void Awake()
{
if (instance != null) //이미 존재하면
{
Destroy(gameObject); //두개 이상이니 삭제
return;
}
instance = this; //자신을 인스턴스로
DontDestroyOnLoad(gameObject); //씬 이동해도 사라지지않게
}
}
몇 년동안 쓰다가 습관이 되어버려 프로젝트 규모 신경안쓰고 쓰다가 당했다.
위에 코드로 만든 gameManager 스크립트를 그대로 오브젝트 하나에다가 넣어주면
다른 오브젝트의 스크립트에서 다음과 같이 접근 가능하다.
public class 다른스크립트 : MonoBehaviour
{
private void Start()
{
//요런식으로 모두가 gameManager에 접근 가능
int nowLeftNum = 999999;
gameManager.instance.enemyLeftAmt = nowLeftNum;
}
}
gameManager.instance.변수나 함수
이런식으로 전역에서 사용가능하다.
DontDestroyOnLoad(gameObject)는 씬 이동시 파괴 되지 않게 하기 위함이다.
#2 스태틱 필드(Static Field) 싱글톤
┌인스턴스 필드? 스태틱 필드?
인스턴스 필드(Instance Field) : 클래스 내부에 선언된 일반변수,
new 키워드로 메모리 주소 만들어서 고유한 메모리를 확보함.
스태틱 필드(Static Field) : static 키워드로 정의된 변수,
인스턴스 없이도 생성 즉시 메모리에 할당됨.
public class Player : MonoBehaviour {
public static Player InstanceField;
public static Player GetInstanceField(){
return InstanceField;
}
public static void SetInstanceField(Player instanceField)
{
Player.InstanceField = instanceField;
}
void Awake()
{
if (InstanceField != null) //이미 존재하면
{
Destroy(gameObject); //두개 이상이니 삭제
return;
}
InstanceField = this; //자신을 인스턴스로
DontDestroyOnLoad(gameObject); //씬 이동해도 사라지지않게
}
}
굳이 gameManager아니어도 되서 Player 클래스로 적용해보았다.
역시나 이경우도 #1그냥 싱글톤처럼 스크립트의 오브젝트가 없어지면 안된다.
잊지말고 DontDestroyOnLoad(gameObject)를 넣어주자.
#3 프로퍼티(Property) 싱글톤
public class Player : MonoBehaviour {
private static Player instance;
public static Player Instance{
get{
return instance;
}
set{
instance = value;
}
}
}
프로퍼티에 대해서 모르겠다면 이분의 글이 아주 자세하게 나온다.
참고로 C#에서는 자동으로 프로퍼티 구현할 수 있어서 다음과 같이 쓸 수 있다.
public class Player : MonoBehaviour {
public static Player Instance{ get; set; }
}
위에 프로퍼티 싱글톤이랑 비슷하고 코드의 길이가 짧아져서 깔끔해졌다.
그런데 이 기능을 다음과 같이 활용가능하다.
public class Player : MonoBehaviour {
public static Player Instance{ get; private set; }
}
달라진 점은 private 키워드를 set 속성 접근자 앞에 붙여주었다.
이러면 오로지 같은 클래스 내에서만 set으로 변경 가능하다.
이러면 전역으로 모두가 접근가능하지만 읽기 전용이 느낌으로 사용 가능하다.
프로퍼티 싱글톤도 마찬가지로 선언 후 Awake에서 한번 세팅 해줘야한다.
void Awake()
{
if (Instance != null) //이미 존재하면
{
Destroy(gameObject); //두개 이상이니 삭제
return;
}
Instance = this; //자신을 인스턴스로
DontDestroyOnLoad(gameObject); //씬 이동해도 사라지지않게
}
번외) 싱글톤 상속 템플릿
https://kimyir.tistory.com/113
유니티 싱글톤 상속 템플릿
안녕하세요.유니티 싱글톤에 대해서 모르시는 분은 없을거라고 생각합니다.다만 매번 클래스에서 싱글톤을 구현하실 때 코드가 많이 더러워지는데요.이런분들을 위해 싱글톤을 구현한 클래스
kimyir.tistory.com
'유니티 > 유니티 관련 지식' 카테고리의 다른 글
유니티 Bootstrap 씬 구현 (0) | 2023.05.19 |
---|---|
유니티 멀티플레이에서 로컬 싱글톤 (2) | 2023.04.12 |
유니티 제네릭<T> 간단하게 정리 (1) | 2023.03.29 |
유니티 Canvas의 World Space 렌더 모드로 UI 만들기 (0) | 2023.03.19 |