업무_메모

[Unity] 전역 매니저 만들기

shine94 2025. 4. 15. 19:57

🎮 유니티로 전역으로 매니저 클래스 만들 수 있을까?

요즘 유니티 공부를 시작했다

유니티 공부를 시작하면서 이해가 안되는 부분이 있었다

딱 하나만 존재하는 매니저 클래스 만들고 싶은데,,,
Main에다 전역 클래스로 그냥 선언하면 될 것 같은데,,, 왜 이렇게 어렵게 만들어야 하지?

 

그 이유는 유니티가 우리가 흔히 아는 C# 프로그램이랑 구조 자체가 다르기 때문이었다

 

 

🧭 유니티에는 Main 함수가 없다?

C# 콘솔 프로젝트나 일반 프로그램을 만들면 static void Main()이란 함수가 딱 있고, 여기서 프로그램이 시작된다

그래서 전역 변수든, 매니저 클래스든, Main 안에서 선언하고 초기화하면 모든 게 깔끔하게 돌아갔다

 

그런데 유니티는?

// 응? Main이 어디 있지?

 

유니티는 이 Main 함수 자체가 없다

유니티는 Main()을 숨겨둔 채, 씬(Scene)을 기준으로 게임을 시작한다

 

 

❓ 그럼, static class를 사용하면 되잖아?

대답은 No다!
총괄 관리(=상태를 가지고, 동작을 관리) 해야 하기 때문에 안된다

 

따라서, 매니저의 역할을 다하기 위해서는 this가 필요하다!!

static class는 프로그램 시작 시 단 한 번 메모리에 올라가긴 하지만, this가 없기 때문에 객체처럼 행동하지는 못한다

 

객체처럼 행동?

   객체라는 건 내 상태(this)를 가지고 있어야 한다

 

this가 없기 때문에

   (1) 유니티의 생명주기를 받을 수 없고

   (2) 컴포넌트를 연결하거나

   (3) 상태를 가진 인스턴스로 행동이 불가능하기 때문이다

 

[static class 어디에 쓰는게 좋나?]

   전역 유틸성 도구에는 딱!!

   하지만 게임의 상태를 관리하는 매니저 역할엔 적합하지 않다

 

 

🎬 유니티의 시작 방식

절대로 헷갈리지 말자!

유니티는 "프로그램"이 아니라 "게임 씬(Scene)"이 먼저 시작된다

 

[때문에]

   GameManager gm = new GameManager();와 같이 만들 수가 없고

   모든 실행 흐름은 씬 안에 배치된 오브젝트의 생명주기에 따라 움직인다

 

[결국,,,]

   내가 생각했던 방법이었던 "전역 클래스를 딱 하나 선언해두는 방식"은 유니티에선 통하지 않는다

 

 

🔄 그래서 처음엔 많이 헷갈릴 수 있다

처음 유니티 공부할 때 이런 생각 들었다

"왜 그냥 전역으로 선언하고 끝내면 안 되는데!?"

 

특히 Android는

MainActivity가 시작점이고,

화면 전환도 startActivity()와 같은 코드로 직접 흐름을 제어하는 적층(stack) 구조

뿐만 아니라 전역 클래스를 미리 선언해서 사용하는 것도 흔하다

 

그래서 Android 개발에 익숙한 사람일수록 유니티의 "씬(Scene) 중심 구조"는 더 낯설고 헷갈릴 수 있을 거 같다

 

참고로 유니티도 내부적으로는 Main 함수가 존재한다
다만 우리가 접근할 수 없고, 유니티가 숨긴 채 자동으로 실행할 뿐이다

 

유니티는 코드가 아니라 씬이 먼저 실행되는 구조라는 걸 잊지 말자!

 

 

🤔 그럼 전역처럼 쓰려면 어떻게 하지?

Unity는 기본적으로 전역 객체를 제공하지 않기 때문에, 우리가 직접 전역처럼 작동하도록 만들어야 한다

 

[그래서 나온 방법]

   @Managers 이름의 GameObject를 만들고, 거기에 싱글톤 스크립트를 붙이기

   (맨 앞에 @를 붙이면, 유니티 씬에서 실수로 삭제하지 말라는 의미의 컨벤션)

using UnityEngine;

public class Managers : MonoBehaviour
{
    private static Managers _instance;
    public static Managers GetInstance()
    {
        Init();
        return _instance;
    }

    static void Init()
    {
        if (_instance == null)
        {
            GameObject go = GameObject.Find("@Managers");
            
            if (go == null)
            {
                go = new GameObject { name = "@Managers" };
                go.AddComponent <Managers>();
            }

            DontDestroyOnLoad(go);
            _instance = go.GetComponent<Managers>();
        }
    }
}

 

 

✅ 마무리

결국, 이 모든 내용의 핵심은 하나다

유니티는 우리가 흔히 알고 있는 코드 중심 흐름이 아니라, "씬 중심으로 움직이는 구조" 라는 것

 

전역처럼 보이는 구조를 만들고 싶다면,

이 유니티의 동작 방식을 이해하고 그에 맞춰 직접 구조를 설계하는 것이 중요하다는 것을 배웠다

 

전역 매니저 하나도, 유니티의 실행 흐름과 생명주기를 먼저 이해한 뒤에 구조를 만들어야 한다

 

✍️ 앞으로 유니티로 구조를 잡을 땐, 항상 "씬이 먼저 시작된다"는 점을 잊지 말자