14. 정처기 + 유니티 singleton

모래사우르스
|2024. 5. 3. 20:55

오전 7:30~9:30, 3~4 정처기 어플리케이션 설계 파트 독서(약 20p)
오후 4:30~7 유니티
오후 8:30~9 정리
 
오늘 전체적으로 집중이 잘 안 되어서 효율이 그닥이다. 의자에 앉아있던 시간은 많은데 뭔가 많이 하진 않음

Singleton

디자인패턴 중의 하나.
저장, UI, 사운드같이 게임의 전범위에 걸쳐서 동작을 해야하는 기능.
오브젝트와 스크립트를 만들어서 구현. (보통 ~~Manager, ~~ManagerScript라고 이름 지음.)

싱글톤의 특징 : 접근성, 유일성, 존속성 (내가 참고한 유튜버가 사용한 단어로, 정식으로 이렇게 정의하는 것은 아니다.)

- 접근성이 편리해짐. 다른 스크립트의 함수를 사용하는 과정이 복잡한데, 싱글톤을 쓰면 이런 과정 필요없음.
- 기능별로 단 하나만 유일하게 존재해야함. 복수로 존재할 시 스크립트들끼리 충돌을 일으키기 때문.
(알아서 하나만 존재하도록 처리해주나봄. 맞나?)
- 씬이 전환되어도 존재하도록 해줘야함. (오브젝트 생성 없이 스크립트만으로 구현할 경우엔 신경쓰지 않아도 됨. 오늘코딩 파이어베이스 영상 참조.. 근데 오브젝트로 구현하는게 훨씬 간단하다고 함)
 

<싱글톤으로 변환하는 작업>

 
클래스 내부에 'static 클래스명 instance' 선언. (변수 이름을 instance로 두는게 관례.)
static의 기능 : 프로그램이 시작되자마자 해당 변수를 메모리가 들고 있게 해줌.
-> 다른 스크립트에서 DataManager.instance로 바로 접근 가능.

 DontDestroyOnLoad(this.gameObject);

 
-> 씬이 전환되더라도 오브젝트를 파괴하지 마라

근데 이렇게 public을 앞에 붙일 경우 어디서든 접근이 가능해져서 보안에 취약함. (그럼 어떡함?)
public 대신 private을 붙인다. 근데 이러면 접근이 안 되잖슴?
그러니 밑에 'public static 클래스명 Instance' 선언. (접근 가능하게 해주는 프로퍼티 생성)

private static DataManager instance = null;
	public static DataManager Instance
	{
		get
		{
			if (instance == null)
			{
				return null
			}
			return instance;
		}
	}


-> 다른 스크립트에서 DataManager.Instance로 바로 접근 가능.
-> 싱글톤 구현한 스크립트 내부에서 public으로 선언한 함수들을 DataManager.Instance.함수명
이렇게 접근 가능.

(왜 이름을 instance랑 Instance로 다르게 주는 거지? get 함수는 뭐지? instance==null 이건 뭐지?
get 내부 이해 못했음.)

싱글톤의 단점 : 위 코드를 보면 static을 씀.
static을 쓰면 쓸 수록 메모리에 고정적으로 할당되는 양이 늘어남. 메모리 용량 부족으로 이어짐.




manager는 엄청 많이 만들어질 것이다. 그 때마다 싱글톤을 만들기는 굉장히 번거롭다.
이를 해결해줄 방법. 하나 만들어놓고 상속시키기~

<generic을 통해서 싱글톤을 간단하게 구현하는 방법>

(위는 기초적인 방식. 싱글톤을 구현하는 방법은 다양하게 존재한다.)
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
(T는 Type을 의미한다.)

(get 내부에 instance = null인 경우가 존재하지 않게 하기 위해 막 이것저것 하는데 조금 이해가 안감.
이 과정이 왜 필요한 것인지? 잘 모르겠음.)

DontDestroyOnLoad()는 해당 오브젝트가 어디 하위에 포함되어있다면(부모 오브젝트가 있다면) 제대로 작동하지 않는다.

이렇게 만든 싱글톤을 상속시켜주면 매우 간단해진다.
<싱글톤 상속하는 방법>
public class ~~Manager : Singleton<~~Manager>


(오늘코딩 https://youtu.be/a5TCCQgdv-E?si=TY_8UQr9ZM0FfJgr 참조)