ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 블루아카이브 루트슈터 팬게임 프로젝트(21) - 게임 저장 시스템
    루트슈터 프로젝트 2024. 1. 23. 18:50

    안녕하세요. 이번에 해볼 것은 플레이어 정보를 세이브 하는 기능 구현입니다. 루트슈터이고 RPG이기 때문에 플레이어의 정보를 저장하고 계속 이어할 수 있도록 해야합니다. 언리얼에서는 기본적으로 세이브 파일을 생성하거나 로드하는 기능을 제공합니다. 

     

     

     

    SaveGame.h

    UCLASS()
    class PROJECTBLUELANDS_API UPlayerStateSave : public USaveGame
    {
    	GENERATED_BODY()
    
    public: 
    	UPlayerStateSave();
    
    public:
    	UPROPERTY()
    	FString SaveSlotName;
    	
    	UPROPERTY()
    	int32 SaveIndex;
    
    	UPROPERTY()
    	int32 Level;
    	
    	UPROPERTY()
    	int32 nowExp;
    
    	UPROPERTY()
    	int64 playerMoney;
    
    	UPROPERTY()
    	FItemData inventory[40];
    
    	UPROPERTY()
    	FItemData gunSlot[3];  
    	
    	UPROPERTY()
    	FItemData armorSlot[3];
    };

     

    언리얼에서 제공하는 USaveGame 클래스를 상속받아 새로운 클래스를 생성합니다. 이곳에는 플레이어의 레벨, 경험치 보유량, 인벤토리, 장비창 상태 등등이 저장됩니다. 그중 가장 필수적인 정보는 세이브 파일의 이름과 인덱스 번호입니다. 이것을 통해 로드를 할 때 세이브 파일을 찾기 때문에 없어서는 안되는 정보입니다. 

     

     

    void ABluelandsGameModeBase::SavePlayerState()
    {
        UPlayerStateSave* SaveGameInstance = Cast<UPlayerStateSave>(UGameplayStatics::CreateSaveGameObject(UPlayerStateSave::StaticClass()));
    
        if(SaveGameInstance && player)
        {
            //세이브 파일 기본정보 
            SaveGameInstance->SaveSlotName = "SaveGameFile";
            SaveGameInstance->SaveIndex = 0;
    
            //플레이어 정보 저장
            SaveGameInstance->Level = player->GetCharacterLevel();
            SaveGameInstance->nowExp = player->nowEXP;
            SaveGameInstance->playerMoney = player->money;
            std::copy(std::begin(player->itemInventory), std::end(player->itemInventory), std::begin(SaveGameInstance->inventory));
            std::copy(std::begin(player->gunSlot), std::end(player->gunSlot), std::begin(SaveGameInstance->gunSlot));
            std::copy(std::begin(player->armorSlot), std::end(player->armorSlot), std::begin(SaveGameInstance->armorSlot));
    
            if(UGameplayStatics::SaveGameToSlot(SaveGameInstance, SaveGameInstance->SaveSlotName, SaveGameInstance->SaveIndex)) UE_LOG(LogTemp, Error, TEXT("saved"));
    
        }
        else UE_LOG(LogTemp, Error, TEXT("save failed!!"));
    }

     

    이 함수는 실제로 세이브를 하는 함수입니다. 세이브 파일 오브젝트를 하나 생성하고 그곳에 넣어야 하는 필요한 정보를 넣은 후 SaveGameToSlot 함수를 통해 실제 세이프 파일을 생성합니다. 이 함수는 bool값 리턴을 하여 세이브가 성공적으로 이루어졌는지 알려주기 때문에 확인을 해보시면 됩니다. 

     

     

    void ABluelandsGameModeBase::LoadPlayerState()
    {
        UPlayerStateSave* LoadGameInstance = Cast<UPlayerStateSave>(UGameplayStatics::CreateSaveGameObject(UPlayerStateSave::StaticClass()));
    
        if(LoadGameInstance && player)
        {
            LoadGameInstance->SaveSlotName = "SaveGameFile";
            LoadGameInstance->SaveIndex = 0;
    
            LoadGameInstance = Cast<UPlayerStateSave>(UGameplayStatics::LoadGameFromSlot(LoadGameInstance->SaveSlotName, LoadGameInstance->SaveIndex));
    
            player->SetLevel(LoadGameInstance->Level);
            player->nowEXP = LoadGameInstance->nowExp;
            player->money = LoadGameInstance->playerMoney;
            std::copy(std::begin(LoadGameInstance->inventory), std::end(LoadGameInstance->inventory), std::begin(player->itemInventory));
            std::copy(std::begin(LoadGameInstance->gunSlot), std::end(LoadGameInstance->gunSlot), std::begin(player->gunSlot));
            std::copy(std::begin(LoadGameInstance->armorSlot), std::end(LoadGameInstance->armorSlot), std::begin(player->armorSlot));
            player->RefreshInventory();
        }
    }

     

    로드 기능을 담당하는 함수입니다. 로드는 세이브의 역순(?)이라고 생각하면 됩니다. 로드한 값을 받아오기 위해 세이브 파일 오브젝트를 하나 생성하고, LoadGameFromSlot의 결과값을 캐스팅 하여 받아온 후 플레이어에게 정보들을 복사해주면 됩니다. 

     

    세이브에 성공한다면 SaveGames폴더에 세이브 파일이 하나 생성되는 것을 볼 수 있습니다. 게임을 종료해도 플레이어에 대한 정보는 이 파일에 계속 남아있으므로 로드하여 게임을 이어갈 수 있습니다. 

     

Designed by Tistory.