본문 바로가기
언리얼 C++ 게임 개발의 정석/12. 프로젝트의 설정과 무한 맵 의 제작

12.2 INI 설정과 애셋의 지연 로딩

by ftftgop3 2024. 5. 6.

INI 설정 : 언리얼 오브젝트의 기본 속성 값을 설정 하는 외부 파일

 

INI 파일을 이용해 ABCharacterSetting 기본 값 설정

언리얼 오브젝트를 초기화 할 떄 INI 파일을 로드해 설정

 

UCLASS (config = ArenaBattle)

초기 단계 시 Config 폴더의 DefaultArenaBattle.ini로 설정

ABCharacterSetting의 CharacterAssets 값 지정

//외부 INI 파일 로드
UCLASS(config=ArenaBattle)
class ARENABATTLESETTING_API UABCharacterSetting : public UObject
{
	GENERATED_BODY()
public:
	UABCharacterSetting();

	//INI 파일 데이터 저장 변수
	UPROPERTY(config)
		TArray<FSoftObjectPath> CharacterAssets;
	
};

 

Config 폴더에 DefaultArenaBattle.ini 추가 

 

 

클래스 기본 객체

모듈에 속한 언리얼 오브젝트을 기본값을 지정해 생성하는 역할

엔진 초기화  엔진 구동에 필요한 모듈을 순차적으로 로드

INI 파일 당 하나의 클래스 기본 객체를 라고 말한다

 

언리얼 오브젝트 클래스 기본 객체는 실행 시 이미 메모리에 올라간 상태

GetDefault 함수를 사용해 클래스 기본 객체를 참조 가능

 

 ABCharacterSetting 언리얼 오브젝트 클래스 기본 객체

생성자를 거처 INI 에 설정한 값으로 할당

ArenraBattleSetting 모듈 이후에 로딩되는 ArenaBattle 모듈에서 GetDefault 함수로 INI 값 로드

 

다른 모듈의 데이터를 접근 

ArenaBattle 모듈의 ABCharacter 에서

ArenaBattleSetting 모둘의 ABCharacterSetting 캐릭터 애셋 목록 접근 

 

ArenaBattle.Build.cs 

ArenaBattleSetting 모듈 사용하게 추가, 구현부 만 사용 할 예정으로 Private 모듈에 추가

// Fill out your copyright notice in the Description page of Project Settings.

using UnrealBuildTool;

public class ArenaBattle : ModuleRules
{
	public ArenaBattle(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] 
        { "Core", "CoreUObject", "Engine", "InputCore","UMG", "AIModule", "GameplayTasks"});

		PrivateDependencyModuleNames.AddRange(new string[] { "ArenaBattleSetting" });

	}
}

 

StreamableManger

게임 진행 중 비동기 방식으로 애셋을 로딩 하는 클래스 사용

하나의 매니저로 사용 하기 때문에 GameInstance의 맴버 변수로 지정

AsyncLoad로 StreamableDelegate 형식의 델리게이트를 넘겨주면

로딩 완료 후 해당 델리게이트를 실행 시켜 준다

 

NCP 생성 시 랜덤으로 캐릭터 애셋 로딩하도록 변경

GameInstance에서 FStreamableManger 선언

 

다른 방식

FStreamableManger은 이미 UAssetManager 선언 되어 있어 

Engin/AssetManager.h 헤더를 포함 후 UAssetManager::GerStreamableManager() 함수로 사용 가능

#include "Engine/StreamableManager.h"

UCLASS()
class ARENABATTLE_API UABGameInstance : public UGameInstance
{
	GENERATED_BODY()
	
public:
	UABGameInstance();

	virtual void Init() override;
	//Level 값을 입력 시 해당 테이블 리턴
	FABCharacterData* GetABCharacterData(int32 Level);
	FStreamableManager StreamableManager;

private:
	//테이블 로드 후 적용 시킬 테이블 객체
	UPROPERTY()
		class UDataTable* ABCharacterTable;
};

 

ABCharacter

랜덤으로 캐릭터를 비동기로 로드 후 스켈레톤 매쉬 변경 

UCLASS()
class ARENABATTLE_API AABCharacter : public ACharacter
{
	GENERATED_BODY()
    
    private:
    //비동기 로드 완료 후 동작 하는 함수 
	void OnAssetLoadCompleted();
    
    private:
    //INI 파일의 데이터
	FSoftObjectPath CharacterAssetToLoad = FSoftObjectPath(nullptr);
    //비동기 로드 시 데이터 핸들
	TSharedPtr<struct FStreamableHandle> AssetStreamingHandle;
}	

void AABCharacter::BeginPlay()
{
	//NPC 상태에서만 동작
	if (!IsPlayerControlled())
	{
		//INI 파일에서 데이터 로드된 UABCharacterSetting 참조
		auto DefaultSetting = GetDefault<UABCharacterSetting>();
		int32 RandIndex = FMath::RandRange(0, DefaultSetting->CharacterAssets.Num() - 1);
		CharacterAssetToLoad = DefaultSetting->CharacterAssets[RandIndex];

		//GameInstance 객체 참조
		auto ABGameInstance = Cast<UABGameInstance>(GetGameInstance());
		if (nullptr != ABGameInstance)
		{
			//비동기 로드 실행, 경로, 델리게이트를 사용해 오브젝트 생성후 OnAssetLoadCompleted() 실행
			AssetStreamingHandle = ABGameInstance->StreamableManager.RequestAsyncLoad(CharacterAssetToLoad, FStreamableDelegate::CreateUObject(this, &AABCharacter::OnAssetLoadCompleted));
			//AssetStreamingHandle = UAssetManager::GetStreamableManager().RequestAsyncLoad(CharacterAssetToLoad, FStreamableDelegate::CreateUObject(this, &AABCharacter::OnAssetLoadCompleted));
		}
	}
}

void AABCharacter::OnAssetLoadCompleted()
{
	//로드 된 데이터를 스켈레톤 메쉬로 캐스트 
	USkeletalMesh* AssetLoaded = Cast<USkeletalMesh>(AssetStreamingHandle->GetLoadedAsset());
	//핸들 초기화 
	AssetStreamingHandle.Reset();
	if (nullptr != AssetLoaded)
	{
		//현재 메쉬 스켈레톤으로 지정
		GetMesh()->SetSkeletalMesh(AssetLoaded);
	}
}

 

언리얼 엔진에서 싱글톤으로 오브젝트 설정 방법

Game singleton class에 지정