How to serialize TArray< MyClass*> ?

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 :frowning:

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:

  1. Because breakpoints doesn’t work in INLINE code I decided to override void Serialize(FArchive &Ar); for my class.
  2. 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.
  3. 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.

Any ideas how to fix or omit this?

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.

With this code:

struct FSaveBranchStruct;
USTRUCT(BlueprintType)
struct SAVETEST_API FSaveBranchStruct
{
	GENERATED_USTRUCT_BODY()
public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Abc")
		FString text;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Abc")
		TArray<FSaveBranchStruct*> moreTexts;
};

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.")); .

You shouldn’t use the struct as a pointer, use it as a value type instead. For the second one try not inline it to get a bit more info.

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.

I had simular problem and to fix it I have to change the construction of my object instance like this:

UReplica* UDialog::CreateReplica()
{
UReplica* r = NewObject(this);//instead of UReplica* r = NewObject();
m_replicas.Add(r);
return r;
}

It object doesn’t know his parent then TArray serializer use UObject serialize method instead of your class method.