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 theGetTransientPackage()
, so no currentUWorld
in it - USaveGame::Serialize() is called directly after instanciation.
"
Solutions?
-
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 useFSaveGameHeader
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 andFSaveGameFileVersion
…
Do you know why these are maintain private in this context? Do you have any warning to put this in the.h
file? -
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 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?
(putFSaveGameFileVersion
,UE4_SAVEGAME_FILE_TYPE_TAG
andFSaveGameHeader
declaration in the.h
OR add a Delegate in GameplayStatics::LoadGameFromMemory() method)
Thanks, I hope i’m understable enough