Structs, how to initialize one as a variable?

There are few more tricks you can do to your Struct to get them even more TArray-friendly.

Below is one of the structs we have in our game; note that we don’t explicitly add default constructor, “GENERATED_BODY()” does that for us, based on assignment in declaration, eg DamageMax = 0;

At the end, we overload “less than”, and “is equal” operators, to allow TArray.Sort() and TArray.Find(). In our case, effect (buff or debuff) is considered identical if it came from the same ParentAbility (spell) is the same effect index (when spells have more than one effect), came from the same instigator, and has the same name. We consider effect “smaller” than other effect, if time remaining is smaller.



USTRUCT(BlueprintType)
struct FAbilityEffect
{
	GENERATED_BODY()

	// Effect Type
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		EAbilityEffectType Type;

	// Minimum damage, if applicable
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		int32 DamageMin = 0;

	// Maximum damage, if applicable
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		int32 DamageMax = 0;

	// Area affected in cm, if applicable
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		float AreaRadius = 0.f;

	// Flag whether damage gets added to current weapon's damage
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		bool AddToWeapon = false;

	// Duration in seconds
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		float Duration = 0.f;

	// Stat Modifier (for Buffs and Debuffs)
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		EStatModifier StatModifier;

	// Modification amount absolute (negative for debuffs, positive for buffs)
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		float ModifierAmount = 0.f;

	// Modification amount percentage/fraction (1.0 is no change, 0.7 for 30% debuff, 1.3 for 30% buff)
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		float ModifierPercentage = 1.f;

	// Leap Inpulse
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AbilityEffect)
		float LeapImpulse = 0;

	// particle effect while under the influence
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = VisualEffects)
		UParticleSystem* EffectParticle = NULL;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = VisualEffects)
		TSubclassOf<AActor> EffectReplacementActorClass = NULL;

	// grounnd hit decal, on the ground of the hit (eg at the feet or enemy)
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = VisualEffects)
		TSubclassOf<class ADecalActor> GroundDecalClass;

	// flag to enable right leg trails
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Properties)
		bool RightLegTrails = false;

	// flag to enable left leg trails
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Properties)
		bool LeftLegTrails = false;

	// animation montage while effect active
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Properties)
		UAnimMontage* Animation = NULL;

	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		UParticleSystemComponent* EffectParticleComponent = NULL;
	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		AActor* EffectReplacementActor = NULL;
	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		FString Name;
	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		ATraverseBaseCharacter* Instigator = NULL;
	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		int32 Index = 0;
	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		float fRemainingTime = 0.f;
	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		int32 iRemainingTime = 0;
	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		float RemainingModifierAmount = 0.f;

	UPROPERTY(BlueprintReadOnly, Category = RuntimeParams)
		UAbility* ParentAbility = nullptr;

	// support for TArray.Sort() -- we sort on float time remaining
	FORCEINLINE bool operator<(const FAbilityEffect& V) const
	{
		return fRemainingTime < V.fRemainingTime;
	}

	// support for TArray.Find()
	FORCEINLINE bool operator==(const FAbilityEffect& Other) const
	{
		if (Index != Other.Index) return false;
		if (ParentAbility != Other.ParentAbility) return false;
		if (Instigator != Other.Instigator) return false;
		if (Name != Other.Name) return false;
		return true;
	}

};


3 Likes