Can't get array of structs and savegame to play along nicely?

I’ve successfully added saving and loading by using a USaveGame.
Now I’m trying to make an unlock system for my game.

My unlocks are stored as an array of a struct, the struct is a name and a bool:

struct FProgress //Unlocks
{
	GENERATED_BODY()
	FName nUnlockName;
	bool bUnlocked;

	FProgress()
	{
		nUnlockName = FName(TEXT("default"));
		bUnlocked = true;
	}

	FProgress(FName UnlockName, bool unlocked)
	{
		nUnlockName = UnlockName;
		bUnlocked = unlocked;
	}

};

Upon game start, I load the player’s profile and all of my variables get retrieved properly, with the exception of my array:

	UPROPERTY(SaveGame, EditAnywhere, BlueprintReadWrite, Category = "Saving")
		FString ProfileName;

	UPROPERTY(SaveGame, EditAnywhere, BlueprintReadWrite, Category = "Saving")
		bool bPixelFilter = true;


	UPROPERTY(SaveGame,EditAnywhere, BlueprintReadWrite, Category = "Saving")
		bool bModelWarping = true;

	UPROPERTY(SaveGame, EditAnywhere, BlueprintReadWrite, Category = "Saving")
		TArray<float> VolumeSettings;


	UPROPERTY(SaveGame)
		TArray<FProgress> Progress;

	UPROPERTY(SaveGame)
		FCustom Player_Custom;

	void CreateSlot(const FString& SlotName)
	{
		ProfileName = SlotName;
	};

Every time I start the game, I check the status of the player’s unlocks:

	void UWSSaveGame::Init(bool newgame, int progresscount)
{
	if (newgame)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString(TEXT("Progress Cleared")));
		Progress.Empty();
	}


	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::FromInt(Progress.Num()));

	AppendItem(FName(TEXT("Skin_Default")));
	Progress[0].bUnlocked = true; //Default Skin needs to always be unlocked.
	AppendItem(FName(TEXT("Skin_Green")));
	AppendItem(FName(TEXT("Skin_Red")));

	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, FString::FromInt(Progress.Num()));


}

However, progress.num is always 0 until I add the the elements myself. (My appentItem function adds unlocks it hasn’t found to the save game’s list).

Before I add them, it logs 0, after it logs 3. Even though it should have the elements from the last play session.
Saving is done after they are added, and loading done before they are added.

Any ideas?

Edit: Figured it out, I was being a dumdum and not getting the order of operations straight, on loading the profile I was getting the savegame’s array before it was ever filled in the first place. Meaning that on save, it would always fill the slot with an empty array,

arrays of structs save fine as long as every member is saveable (FName + bool both are) and the UPROPERTY has the SaveGame flag, which yours do. usual culprit when everything except the array loads: the array never got copied into the save object before SaveGameToSlot, or you save one slot name and load another. print the array length right before save and right after load to see which side drops it.

if you want the slot headache gone, Advanced Save System, a save/load system plugin for Unreal Engine 5, does automatic serialization + slots + async in BP and C++: Advanced Save System. on sale atm ($23.93).

You bringing up old threads to spam your products?

2 Likes