How do i initialize a ustruct member?

Hello, i have the following struct:

USTRUCT()
struct FTest
{
	GENERATED_USTRUCT_BODY()

	float Var;

	UPROPERTY(EditDefaultsOnly, Category = "My category")
	float MaxVar;

	FTest() {}
};

Max Var is set through the editor on the Defaults panel, and when i start the game i want to set Var = MaxVar but since i don’t have a method like PostInitializeComponents to get the real value of MaxVar i can’t make that attribution. The only way i have so far is to set it manually in the class where i use this struct:

.h

FTest Test;

.cpp

void AMyCharacter::PostInitializeComponents()
{
	Super::PostInitializeComponents();

	Test.Var= Test.MaxVar;
}

I wanted to avoid that if there as better way. Thank you.

Edit: I tried that way and for some reason i can’t edit the Var value, they all stay the same, event setting it to a constant value like Test.Var = 50; it will revert to 0.

Edit 2: Ok so i figured out the problem with the values not changing, the problem was that i was using a TArray of FTest and the for(FTest Test : Tests) apparently does not give me the actual value inside the array, it gives me a copy, so when i switched to a for(uint8 i = 0 ; i < Tests.Num() ; i++) and access directly the value started changing. I think this is a bug on the first for method, so i will create a different question to see if it’s a bug or not.

1 Like

Thank you for your answer, but my problem is that i need to init Var with the value that MaxVar has, and we only know that after the game starts, because at the beginning it’s 0. I edited my answer because i tried doing the manual way and for some reasons the Var value stays unchanged even if i set it to Test.Var = 50; he will still be 0, really weird.

There is a special meta tag used to specify default values. In the following example I just initialize a vector that is used as a scale value and a simple float value:

USTRUCT(BlueprintType)
struct FMyStruct
{
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=MyStruct, meta=(MakeStructureDefaultValue = "1,1,1"))
	FVector Scale3D;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=MyStruct, meta=(MakeStructureDefaultValue = "1"))
	float MyFloat;
};

You can also clamp values using the meta: meta=(ClampMin=“0”, ClampMax=“255”). There a lots of usable modifiers: https://docs.unrealengine.com/latest/INT/API/Runtime/CoreUObject/UObject/UM___84/index.html

Cheers,
Moss

1 Like

Ok I see, I think this can be done overwriting the serialization function in your struct:

FORCEINLINE friend FArchive& operator<<(FArchive& Ar, FTest& TestStruct)
{
    // This gets called when the struct is serialized and deserialized. So you could eventually set the value of Var once you have deserialized the value of MaxVar.
    Ar << TestStruct.MaxVar;
    TestStruct.Var = TestStruct.MaxVar;
    return Ar;
}

I’ve not tested the snipped though. Also this is used in both serialization and deserialization so you my do not want to make the assignation on serialization (there might be a flag in the FArchive to see if its a write or a read operation.

This trick seams to work for stuff that is actually serialized into the level but not for things that get spawned in runtime.

Cheers,
Moss

Thanks, i will try it out :slight_smile: