유니티 싱글톤 2

박지예·2022년 5월 26일
0

공부

목록 보기
29/42

너무 자연스럽게 알고 있는 것들을 정리해보자.

내가 어떻게 이걸 배웠더라, 정확히 어떤 뜻이더라,를 알아야 남들이 이해하기 쉽게 알려줄 수 있다.

싱글톤 패턴이란

프로그래밍 디자인 패턴 중에 가장 빈번하게 사용하는 패턴이라 할 수 있다.
오직 한 개의 클래스 인스턴스만 갖도록 보장하고, 이에 대한 전역적인 접근점을 제공한다.

이렇게 하지 마세요😅

유니티 뉴비 시절, Manager 클래스에 일일히 필요한 스크립트를 가지고 있는 오브젝트를 할당 시켰다.


으악

이렇게 되면 새로운 스크립트를 할당할때마다 저렇게 코드를 추가해줘야한다는 불편함과, 씬 이동이 있을 때 관련 스크립트를 가지고 있는 오브젝트를 모두 옮겨야한다는 단점이 있었다.

난 꽤 오래 저런걸 싱글톤 패턴이라고 쓰고 있었다.

그러니 나같은 사람들이 없길 바라며 이 글을 써본다

싱글톤의 역할

  1. 게임 시스템에서 전체를 관리한다
  2. 게임 시스템 상의 전역 변수 역할을 한다
  3. 씬 로드시 데이터가 파괴되지 않고 유지 된다
  4. 여러 오브젝트가 접근할 수 있는 데이터 활용

쉽게 코드로 알아보자

싱글톤 코드

using UnityEngine;

/// <summary>
/// 싱글톤 베이스 
/// </summary>
/// <typeparam name="T">Singleton 클래스를 상속받은 T타입만 올 수 있음</typeparam>
public abstract class Singleton<T> : MonoBehaviour where T : Singleton<T>
{
    // 씬 변경 시 파괴하지 않을 건지
    public bool isDontDestroy;

    // 인스턴스 객체를 담을 필드
    private static T _instance;

    public static T Instance
    {
        get
        {
            // 인스턴스가 없는지 확인
            if (_instance == null)
            {
                // 없다면 씬에서 찾음
                _instance = FindObjectOfType(typeof(T)) as T;

                // 찾아도 없다면
                if (_instance == null)
                {
                    // 생성하여 T타입 컴포넌트를 붙임
                    var go = new GameObject(typeof(T).ToString());
                    _instance = go.AddComponent<T>();
                }
            }

            // 결과적으로 반환 시에는 인스턴스는 무조건 존재함
            return _instance;
        }
    }

    public virtual void Awake()
    {
        // Awake가 들어왔다는 것은 씬 장면의 하이라키상에 객체가 존재한다는 뜻
        // 이 때 경우는 2가지 -> 내가 미리 씬에 T타입 스크립트를 갖는 객체를 배치했거나
        //                      다른 스크립트를 통해 T타입 인스턴스에 접근하여 객체가 생성된 경우

        // 이 때 싱글톤 사용에 규칙성을 부여
        // ex) 난 무조건 싱글톤을 갖는 객체라면 씬에 미리 스크립트를 갖는 객체를 배치하는 식으로 사용한다

        // 위의 경우, 타 스크립트에서 awake 시점보다 빠른 시점에 t타입객체에 접근하지 않았다면
        // 인스턴스는 무조건 null임

        // 그럼 null이 아닌 경우, 씬에 t타입 객체가 하나 더 생성된 경우
        // 해당 객체를 파괴함으로써 결과적으로 단 하나의 인스턴스만을 유지할 수 있다.

        if (_instance == null)
        {
            _instance = this as T;

            if (isDontDestroy)
                DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

그럼 사용은 어떻게 할까?


요로코롬 상속받고 T타입 클래스를 상속하여 쓸 수 있다

싱글톤 주의할점

너무 편하게 접근 할 수 있다 보니까, 마구잡이로 사용하여 코드가 꼬일 수 있다.

이렇게 말하긴 하지만, 기능경기대회같은 시간 제한이 있는 상황에는 자주 사용했다.
Manager 스크립트만 접근 할 수 있게 해보자.
기능별로 묶여 정리되어 있게 해두는 것이다.

profile
언젠간 바다로 갈거야!🐋

0개의 댓글