What is the best way to populate USaveGame on LoadGame before serialization?

Hi there,

First, sorry for my english, I try to do my best but i’m not fluent at all.

To give you more details:

##My Needs##

I need to populate my derived USaveGame object with an UObject containing the current UWorld (as a WorldContextObject) on the Load Game process BEFORE serialization.

This to allow my USaveGame object to use current world to spawn actors as suggest here (the response by Ben Zeigler) or retrieve some objects from UGameInstance.

##Problems##

I try to use the native Save Game System which has been improve since by Ben Zeigler and Mike Beach (2 years ago) to avoid re-coding my own system.

The thing is I can’t do that with this new system, in the UGameplayStatics::LoadGameFromMemory() we can see 2 things which prevents me to do that:

  • the USaveGame is instanciated with the GetTransientPackage(), so no current UWorld in it
  • USaveGame::Serialize() is called directly after instanciation.

"

Solutions?

  1. My first attempt was to create my own loading function, I just had to copy/paste UGameplayStatics::LoadGameFromMemory() and populated my UsaveGame object before serialization with whatever I want. I was surprised when I did it cause the function use FSaveGameHeader which is declared in the CPP files, so I couldn’t re-use it as such, and i had to copy it with its other dependencies: UE4_SAVEGAME_FILE_TYPE_TAG static int and FSaveGameFileVersion
    Do you know why these are maintain private in this context? Do you have any warning to put this in the .h file?

  2. My second though was to think about how to make the actual code more extensible. I’m guessing that passing an optional delegate as parameter of this function should do the trick like:

In Engine\Source\Runtime\Engine\Classes\Kismet\GameplayStatics.h

DECLARE_DELEGATE_OneParam(FLoadSaveGameObjectDelegate, USaveGame*);

In Engine\Source\Runtime\Engine\Private\GameplayStatics.cpp

// line 2077
LoadGameFromMemory(const TArray<uint8>& InSaveData, FLoadSaveGameObjectDelegate const& InDelegate)  
// line 2103  
if (InDelegate.IsBound())  
{
   InDelegate.Execute(OutSaveGameObject)
}

This implies additional codes to make the Delegate optionnable (can be inspired from FTimerUnifiedDelegate) but you get the idea.

Questions

So questions are:

  • Am I in a complete wrong direction :smiley: and there is an already better solution which fit my needs?
  • If not, do you think my solutions worth to be in the engine code?
    (put FSaveGameFileVersion , UE4_SAVEGAME_FILE_TYPE_TAG and FSaveGameHeader declaration in the .h OR add a Delegate in GameplayStatics::LoadGameFromMemory() method)

Thanks, I hope i’m understable enough :smiley:

Hi, it’s an old topic but did you solve the issue?