I might’ve been stupid, but I think I solved this somehow…
FYI: I tried creating the save system to be both Sync and ASync, and to be quite easy to use, and accessible as possible.
UCndSys_Save - is a save system object.
UCndSysSave_GD - is data structure class containing all player data.
The issue with creating the save object, which resulted in crash, during initialization was… that the game data structure class (Cnd_SaveObject_GD) was called from the inside of the save system, not from my CndGameInstance when I tried using this:
Cast<UCndSysSave_GD>(UGameplayStatics::CreateSaveGameObject(UCndSysSave_GD::StaticClass()));
To solve this, I added my data struct class to this function as a parameter:
CndSys_Save_Data.h
void BPF_GD_SaveLoad(UCndSysSave_GD* GameData, ECndSysSave_GD_SaveLoadType SaveLoadType, bool ASync, FString SlotName, int32 UserIndex,
ECndSysSave_GD_SaveLoadIndividual GD_IndividualType, TArray<TEnumAsByte<ECndSysSave_GD_Type>> Array_GD_Type);
And this fixed the crash during engine initialization, when CndGameInstance called the save system.
CndGameInstance.h
void UCndGameInstance::BPF_Init()
{
// If save type is set to GD_Individual, save certain data only
CndArray_GD_Type.Empty();
// Load Game Data Synchronous
CndSys_Save->BPF_GD_SaveLoad(CndSaveData, GD_Load, false, CndGD_SlotName, CndGD_User_Index, GD_All, CndArray_GD_Type);
}
CndSysSave_Data.cpp
void UCndSysSave_Sys::BPF_GD_SaveLoad(UCndSysSave_GD* GameData, ECndSysSave_GD_SaveLoadType SaveLoadType, bool ASync, FString SlotName, int32 UserIndex,
ECndSysSave_GD_SaveLoadIndividual GD_IndividualType, TArray<TEnumAsByte<ECndSysSave_GD_Type>> Array_GD_Type)
{
if (SaveLoadType == GD_Load)
{
if (DoesSaveExists(SlotName, UserIndex))
{
if (ASync)
{
// Broadcast event once data is being loaded via ASync
OnGD_LoadStart.Broadcast();
DEL_CndGD_ASyncLoad.BindLambda(
[this, GameData, GD_IndividualType, Array_GD_Type](const FString& SlotName, const int32 UserIndex, USaveGame* LoadedGame)
{
if (LoadedGame)
{
// Cnd_SaveInstance = Cast<UCndSysSave_Sys>(LoadedGame);
BPF_PTR_GD_SaveLoad(GameData, GD_Load, true, SlotName, UserIndex, GD_IndividualType, Array_GD_Type); // Update game state - ASync
}
else
{
UE_LOG(LogTemp, Error, TEXT("CND_DEBUG: SaveSys - Failed to load data asynchronously from slot: %s"), *SlotName);
}
}
);
}
else // if ASync is not true
{
BPF_PTR_GD_SaveLoad(GameData, GD_Load, false, SlotName, UserIndex, GD_IndividualType, Array_GD_Type); // Update game state - Sync
}
}
else // Save Does Not Exists
{
BPF_GD_CreateNew(GameData);
}
}
}
void UCndSysSave_Sys::BPF_GD_CreateNew(UCndSysSave_GD* GameData)
{
UE_LOG(LogTemp, Log, TEXT("CND_DEBUG - SAVE SYS (GD): Creating new save game object."));
// Create new save game object
GameData = Cast<UCndSysSave_GD>(UGameplayStatics::CreateSaveGameObject(UCndSysSave_GD::StaticClass()));
}