0. 개요

게임이 저장된 슬롯이라면 로드 메뉴에 진입했을 때 Taken 슬롯이 노출되도록 저장 상태를 열거형으로 만들어 관리할 것이다.

 

1. 저장 상태

(1) LoadScreenSaveGame 클래스에 열거형 선언

UENUM(BlueprintType)
enum ESaveSlotStatus
{
	Vacant,
	EnterName,
	Taken
};

 

 

(2) MVVM_LoadSlot에 슬롯 상태를 멤버 변수로 저장

	UPROPERTY()
	TEnumAsByte<ESaveSlotStatus> SlotStatus;

 

 

(3) AuraGameModeBase에서 저장 불러오기

	ULoadScreenSaveGame* GetSaveSlotData(const FString& SlotName, int32 SlotIndex) const;
ULoadScreenSaveGame* AAuraGameModeBase::GetSaveSlotData(const FString& SlotName, int32 SlotIndex) const
{
	USaveGame* SaveGameObject = nullptr;
	if (UGameplayStatics::DoesSaveGameExist(SlotName, SlotIndex))
	{
		// 저장 게임 오브젝트 가져오기
		SaveGameObject = UGameplayStatics::LoadGameFromSlot(SlotName, SlotIndex);
	}
	else
	{
		// 없으면 생성
		SaveGameObject = UGameplayStatics::CreateSaveGameObject(LoadScreenSaveGameClass);
	}

	// 커스텀 저장 게임 오브젝트로 캐스팅
	ULoadScreenSaveGame* LoadScreenSaveGame = Cast<ULoadScreenSaveGame>(SaveGameObject);

	return LoadScreenSaveGame;
}

 

 

(4) 커스텀 세이브 게임 오브젝트에 저장 상태 멤버 변수 선언

	UPROPERTY()
	TEnumAsByte<ESaveSlotStatus> SaveSlotStatus = Vacant;

 

(4-1) AuraGameModeBase의 SaveSlotData 함수에서 세이브 게임 오브젝트의 저장 상태 멤버 변수 변경

void AAuraGameModeBase::SaveSlotData(UMVVM_LoadSlot* LoadSlot, int32 SlotIndex)
{
	// 이미 존재하는 슬롯에 저장하려 하면 기존 슬롯의 저장 데이터를 제거
	if (UGameplayStatics::DoesSaveGameExist(LoadSlot->LoadSlotName, SlotIndex))
	{
		UGameplayStatics::DeleteGameInSlot(LoadSlot->LoadSlotName, SlotIndex);
	}

	// 저장 게임 오브젝트 생성
	USaveGame* SaveGameObject = UGameplayStatics::CreateSaveGameObject(LoadScreenSaveGameClass);

	// 커스텀 저장 게임 오브젝트로 변환하여 플레이어 이름 할당
	ULoadScreenSaveGame* LoadScreenSaveGame = Cast<ULoadScreenSaveGame>(SaveGameObject);
	LoadScreenSaveGame->PlayerName = LoadSlot->PlayerName;
	LoadScreenSaveGame->SaveSlotStatus = Taken;

 

 

(5) MVVM_LoadScreen 뷰 모델의 데이터 불러오기 함수

void UMVVM_LoadScreen::LoadData()
{
	AAuraGameModeBase* AuraGameMode = Cast<AAuraGameModeBase>(UGameplayStatics::GetGameMode(this));

	for (const TPair<int32, UMVVM_LoadSlot*> LoadSlot : LoadSlots)
	{
		// 각 슬롯의 키(슬롯 인덱스)-페어(슬롯)를 사용해 세이브 데이터를 가져오기
		ULoadScreenSaveGame* SaveObject = AuraGameMode->GetSaveSlotData(LoadSlot.Value->LoadSlotName, LoadSlot.Key);

		// 데이터에서 불러오기
		const FString PlayerName = SaveObject->PlayerName;

		TEnumAsByte<ESaveSlotStatus> SaveSlotStatus = SaveObject->SaveSlotStatus;

		LoadSlot.Value->SlotStatus = SaveSlotStatus;
		LoadSlot.Value->SetPlayerName(PlayerName);
		LoadSlot.Value->InitializeSlot();
	}
}

- 슬롯의 키-페어를 이용하여 GameplayStatics를 통해 세이브 데이터를 가져온다.

- 세이브 데이터에서 플레이어 이름과 상태를 가져와 슬롯에 지정한다.

 

 

(6) MVVM_LoadSlot 뷰 모델의 슬롯 초기화 델리게이트 수정

void UMVVM_LoadSlot::InitializeSlot()
{
	const int32 WidgetSwitcherIndex = SlotStatus.GetValue();
	SetWidgetSwitcherIndex.Broadcast(WidgetSwitcherIndex);
}

이제 각 슬롯에게 슬롯 상태가 부여되었으므로 해당 값을 이용해서 델리게이트에 넘겨준다.

 

 

(7) MVVM_LoadScreen의 BeginPlay에서 데이터 불러오기

void ALoadScreenHUD::BeginPlay()
{
	Super::BeginPlay();

	// 로드 메뉴의 뷰 모델 생성
	LoadScreenViewModel = NewObject<UMVVM_LoadScreen>(this, LoadScreenViewModelClass);

	// 뷰 모델 초기화 - 로드 슬롯의 뷰 모델 생성
	LoadScreenViewModel->InitializeLoadSlots();

	// 로드 메뉴의 뷰 생성
	LoadScreenWidget = CreateWidget<ULoadScreenWidget>(GetWorld(), LoadScreenWidgetClass);
	LoadScreenWidget->AddToViewport();

	// 로드 메뉴의 뷰를 블루프린트에서 초기화 시킴
	LoadScreenWidget->BlueprintInitializeWidget();

	// 데이터 불러오기
	LoadScreenViewModel->LoadData();
}

 

2. 로직 흐름

(1) LoadScreenHUD에서 슬롯 위젯 생성 후 데이터 불러오기 함수 호출

 

(2) MVVM_LoadScreen에서 데이터 불러오기 함수 실행

- 각 슬롯을 순회하여, 키(슬롯 인덱스)-값(슬롯의 뷰모델) 쌍을 이용해 게임 모드의 세이브 데이터를 가져오기

 

(3) AuraGameModeBase에서 호출된 GetSaveSlotData 함수

- UGameplayStatics의 LoadGameFromSlot 함수를 사용하여 저장 게임 오브젝트 가져옴

- 가져온 오브젝트를 커스텀 세이브 게임 오브젝트로 캐스팅하여 리턴

 

(4) MVVM_LoadScreen의 데이터 불러오기 함수 로직 진행 중

- 가져온 데이터를 이용해 위젯의 상태, 플레이어 이름을 변화시킴

- 슬롯의 InitializeSlot 함수를 호출하여 위젯 체인져에게 델리게이트 전달 -> 위젯 전환

 

 

3. 디버그

(1) 슬롯 상태가 정상적으로 지정되지 않음

void UMVVM_LoadScreen::NewSlotButtonPressed(int32 Slot, const FString& EnteredName)
{
	// 게임모드 가져오기
	AAuraGameModeBase* AuraGameMode = Cast<AAuraGameModeBase>(UGameplayStatics::GetGameMode(this));

	// 슬롯 플레이어 이름을 입력한 이름으로 지정
	LoadSlots[Slot]->SetPlayerName(EnteredName);
	LoadSlots[Slot]->SlotStatus = Taken;

슬롯 생성 버튼을 누르면 슬롯 상태를 Taken으로 지정한다.