언리얼 엔진 5/공부

[언리얼 엔진 5] 싱글톤 패턴 (Subsystem)

ciel45 2024. 4. 10. 21:31

유니티에서 싱글톤을 구현하는 방법은 다음과 같다.

using UnityEngine;

public class Singleton : MonoBehaviour
{
    public static Singleton instance;

    private void Awake()
    {
        if (instance == null)
            instance = this;
    }

}

 

 

그런데 언리얼 엔진 5에서 GameManager같은 것을 유니티에서와 같은 방식으로 싱글톤으로 만드려고 하면, 엔진의 시스템 상 차이때문에 쉽지 않다.

 

 

하지만 언리얼 엔진 5에서는 UGameInstanceSubsystem을 상속받은 클래스를 만듦으로써 손쉽게 싱글톤 클래스를 만들 수 있다.

 

 

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/programming-subsystems-in-unreal-engine?application_version=5.3

 

프로그래밍 서브시스템

언리얼 엔진 4 의 프로그래밍 서브시스템 개요입니다.

dev.epicgames.com

 

 

서브시스템의 종류가 여러가지가 있는데, <~~>SubSystem은 <~~>와 수명 주기가 똑같다. 

 

GameManager 클래스는 보통 게임 전반에 걸쳐 데이터를 조작하기 때문에, UGameInstance와 수명을 같이하게 된다.

따라서 GameManager는 UGameInstanceSubsystem를 상속받는 것이 적합하다.

 

이외에도 필요에 따라 맞는 서브시스템을 상속받아주면 된다.

 

서브시스템 사용의 장점은 공식 문서에 잘 나와있다.

 

다음은 프로젝트에서의 사용 예시이다.

// UGameInstanceSubsystem을 상속받은 UGameManager

/* ... */

UCLASS()
class KANNATPS_API UGameManager : public UGameInstanceSubsystem
{
	GENERATED_BODY()
	/*  ... */

	UFUNCTION(BlueprintCallable)
	void ChangeDefaultVolume(float volume);
    
	UPROPERTY(BlueprintReadOnly)
	TArray<AEnemy*> ActiveEnemies;

	UPROPERTY(BlueprintReadOnly)
	bool IsAlerted;
    
	AKannaCharacter* KannaCharacter;
};

 

이 GameManager는 다른 곳에서 다음과 같은 방법으로 참조할 수 있다.

GetGameInstance()->GetSubsystem<UGameManager>()->ActiveEnemies.Add(this);

if (GetGameInstance()->GetSubsystem<UGameManager>()->IsAlerted)
{
	NoticePlayer();
}
UGameManager* GM = GetGameInstance()->GetSubsystem<UGameManager>();
GM->KannaCharacter = this;
GM->ChangeDefaultVolume(1.f);
GM->IsAlerted = false;

 

GetGameInstance()로 UGameInstance를 불러오고, 그 Subsystem인 UGameManager를 참조하는 것이다.

 

 

이렇게 만든 싱글톤 클래스는 블루프린트에서도 편하게 참조할 수 있다.