So my main goal is to serialize this class, which thanks to TArray< USaveBranch* > can create ‘tree structure’ which is very important for me:
typedef class USaveBranch USaveBranch;
UCLASS(BlueprintType)
class SAVETEST_API USaveBranch : public USaveGame
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Abc")
FString text;
/** how to serialize this...*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Abc")
TArray<USaveBranch*> moreTexts;
};
FORCEINLINE FArchive &operator <<(FArchive &Ar, USaveBranch& SB)
{
Ar << SB.text;
Ar << SB.moreTexts;
}
I was reading This Save System Tutorial but for me build in ‘Slot Saving System’ is fine, I just have problem with serializing this TArray.
With this code, if I won’t restart game, just save and load it seems to work but after restarting and loading it prints out only text from “Root” and knows count of saved ‘moreTexts’, but those are empty.
Any tip or help would be great!! I’ve run out of ideas
I’ve not tried out your setup yet but what you could do instead is something like the following to save your tree (the code is not tested though, just written here ^^):
FORCEINLINE FArchive &operator <<(FArchive &Ar, USaveBranch& SB)
{
Ar << SB.text;
if (Ar.IsLoading())
{
int32 NumBunches;
USaveBranch SaveBunch;
Ar << NumBunches;
for (int32 ObjIndex = 0; ObjIndex < NumBunches; ObjIndex++)
{
Ar << SaveBunch;
SB.moreTexts.Add(SaveBunch);
}
}
else if (Ar.IsSaving())
{
int32 NumBunches = SB.moreTexts.Num();
Ar << NumBunches;
for (int32 ObjIndex = 0; ObjIndex < NumBunches; ObjIndex++)
{
Ar << SB.moreTexts[ObjIndex]
}
}
return Ar;
}
The idea is to serialize the items in the array itself.
Thank You for help. Unfortunately this doesn’t work. My last attempts were very similar to your code.
Here is what I noticed so far:
Because breakpoints doesn’t work in INLINE code I decided to override void Serialize(FArchive &Ar); for my class.
UE handles serializing TArray thanks to friend FArchive& operator<<(FArchive& Ar, TArray& A) in Engine\Source\Runtime\Core\Public\Containers\Array.h. In short this function is almost the same to what You wrote, so simply passing whole TArray should be fine, as long as UE knows how to serialize MyClass, if I’m not mistaken. Anyway I tested two options and ended with the same problem.
The most strange thing for me is why line “Ar << SB.moreTexts[ObjIndex]” uses FArchive& FObjectAndNameAsStringProxyArchive::operator<<(class UObject*& Obj) in Engine\Source\Runtime\CoreUObject\Private\Serialization\ArchiveUObject.cpp instead of my overloaded operator or overrided Serialize funciton. This is reason of saving data incorrectly.
For the inline issue just move the implementation to C++. Yeah arrays should serialize just fine. The third one is a bit odd really, have you tried not using UObjects for the whole thing? You could also use an UStruct and create the UObjects when you load them, structs should have the override issue here.
I get this: Error 1 error code: OtherCompilationError (5). When I delete UPROPERTY from TArray it compiles but then I’m unable to get it from Blueprints.
Back to your first idea I extended it a bit and created simple recursive function to save SaveBranch. This way I don’t need to use Ar << SB.moreTexts[ObjIndex]. But I’m unable to test it because when trying to load, code jumps from USaveBranch SaveBunch; to E_CLOG(!ThreadContext.IsInConstructor, LogUObjectGlobals, Fatal, TEXT("FObjectInitializer::Get() can only be used inside of UObject-derived class constructor.")); .
As a value it gives me the same error while compiling, just noticed it is more explained in Output tab Struct recursion via arrays is unsupported for properties. Second one was made via Serialize function and unfortunately this is all I get.
This is way harder than I thought it will be… I’ll be trying bit more to serialize class, that’s what should work, at least it seems to work for others.