Target Data¶
FGameplayAbilityTargetData is the currency of the targeting system. It is a polymorphic struct that carries targeting results — hit results, actor lists, world locations, or custom data — from the targeting step to wherever it needs to go (effect application, spawning, custom logic).
FGameplayAbilityTargetData — The Base¶
The base struct is abstract and defines the interface that all target data types share:
USTRUCT()
struct FGameplayAbilityTargetData
{
// Returns all targeted actors
virtual TArray<TWeakObjectPtr<AActor>> GetActors() const;
// Override to return a hit result
virtual const FHitResult* GetHitResult() const;
// Returns an origin transform
virtual FTransform GetOrigin() const;
// Returns a target/end point
virtual FVector GetEndPoint() const;
virtual FTransform GetEndPointTransform() const;
// Apply a gameplay effect to each target
TArray<FActiveGameplayEffectHandle> ApplyGameplayEffect(
const UGameplayEffect* GameplayEffect,
const FGameplayEffectContextHandle& InEffectContext,
float Level, FPredictionKey PredictionKey);
// Apply a pre-built spec
virtual TArray<FActiveGameplayEffectHandle> ApplyGameplayEffectSpec(
FGameplayEffectSpec& Spec, FPredictionKey PredictionKey);
};
The key thing to understand is that target data is polymorphic. The base struct defines the interface, and subclasses provide the actual data. This lets the same consuming code work regardless of whether the target data came from a line trace, a radius overlap, or a custom selection method.
FGameplayAbilityTargetDataHandle — The Container¶
You never pass raw FGameplayAbilityTargetData around. Instead, you use FGameplayAbilityTargetDataHandle, which is a smart container that:
- Holds one or more
FGameplayAbilityTargetDataentries (viaTSharedPtr) - Supports polymorphism (each entry can be a different subclass)
- Implements
NetSerializefor replication - Is the type used in Blueprint pins and function signatures
FGameplayAbilityTargetDataHandle Handle;
// Add target data entries
FGameplayAbilityTargetData_SingleTargetHit* HitData =
new FGameplayAbilityTargetData_SingleTargetHit(HitResult);
Handle.Add(HitData);
// Iterate
for (int32 i = 0; i < Handle.Num(); ++i)
{
const FGameplayAbilityTargetData* Data = Handle.Get(i);
if (Data)
{
TArray<TWeakObjectPtr<AActor>> Actors = Data->GetActors();
// ...
}
}
Ownership and lifetime
Target data inside a handle is managed via TSharedPtr with a custom deleter (FGameplayAbilityTargetDataDeleter) that properly destructs the polymorphic struct. Use new to create target data and Handle.Add() to transfer ownership — the handle will clean it up.
Built-in Target Data Types¶
The engine provides several concrete target data types.
FGameplayAbilityTargetData_SingleTargetHit¶
The most commonly used type. Wraps a single FHitResult:
USTRUCT()
struct FGameplayAbilityTargetData_SingleTargetHit : public FGameplayAbilityTargetData
{
UPROPERTY()
FHitResult HitResult;
UPROPERTY()
bool bHitReplaced = false;
};
This is what you get from line traces. It provides the hit actor, impact location, normal, bone name, and all other FHitResult data.
FGameplayAbilityTargetData_LocationInfo¶
Contains two FGameplayAbilityTargetingLocationInfo entries — a source location and a target location. Used for location-based targeting (e.g., "cast from here to there"):
USTRUCT()
struct FGameplayAbilityTargetData_LocationInfo : public FGameplayAbilityTargetData
{
UPROPERTY()
FGameplayAbilityTargetingLocationInfo SourceLocation;
UPROPERTY()
FGameplayAbilityTargetingLocationInfo TargetLocation;
};
FGameplayAbilityTargetingLocationInfo supports three location types:
| Type | Description |
|---|---|
LiteralTransform |
A raw world transform |
ActorTransform |
The transform of an associated actor |
SocketTransform |
A socket on the player's skeletal mesh |
FGameplayAbilityTargetData_ActorArray¶
Holds a list of actors, useful for AoE abilities or multi-target skills:
USTRUCT()
struct FGameplayAbilityTargetData_ActorArray : public FGameplayAbilityTargetData
{
UPROPERTY()
FGameplayAbilityTargetingLocationInfo SourceLocation;
UPROPERTY()
TArray<TWeakObjectPtr<AActor>> TargetActorArray;
};
Creating Custom Target Data¶
For project-specific targeting needs, subclass FGameplayAbilityTargetData:
USTRUCT()
struct FMyTargetData_Terrain : public FGameplayAbilityTargetData
{
GENERATED_USTRUCT_BODY()
UPROPERTY()
FVector TargetLocation;
UPROPERTY()
float AreaRadius;
UPROPERTY()
FGameplayTag TerrainType;
virtual TArray<TWeakObjectPtr<AActor>> GetActors() const override
{
// Could do an overlap check here, or return empty
return {};
}
virtual FVector GetEndPoint() const override
{
return TargetLocation;
}
virtual bool HasEndPoint() const override
{
return true;
}
virtual UScriptStruct* GetScriptStruct() const override
{
return FMyTargetData_Terrain::StaticStruct();
}
};
GetScriptStruct is required for serialization
If you want your custom target data to replicate, you must override GetScriptStruct() to return the correct struct type. This is how the serialization system knows which struct to construct on the receiving end.
Registering for NetSerialize¶
Custom target data types need to be registered with the gameplay ability target data serialization system. You do this by implementing NetSerialize and registering the struct:
bool FMyTargetData_Terrain::NetSerialize(
FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess)
{
Ar << TargetLocation;
Ar << AreaRadius;
TerrainType.NetSerialize(Ar, Map, bOutSuccess);
bOutSuccess = true;
return true;
}
Using Target Data with Effects¶
The common flow is: receive target data, create an effect spec, apply it to the targets:
void UMyAbility::OnTargetDataReady(
const FGameplayAbilityTargetDataHandle& Data)
{
FGameplayEffectSpecHandle SpecHandle =
MakeOutgoingGameplayEffectSpec(DamageEffectClass, GetAbilityLevel());
// Apply to all targets in the handle
TArray<FActiveGameplayEffectHandle> AppliedHandles =
K2_ApplyGameplayEffectSpecToTarget(SpecHandle, Data);
K2_EndAbility();
}
The ApplyGameplayEffectSpec on FGameplayAbilityTargetData will route the effect to each targeted actor, using the hit result or actor list from the target data.
Confirmation Types¶
When using target actors to produce target data, the confirmation behavior is controlled by EGameplayTargetingConfirmation:
| Confirmation | Behavior |
|---|---|
Instant |
Data is produced immediately, no user input |
UserConfirmed |
Waits for the user to press confirm |
Custom |
The ability decides when data is ready |
CustomMulti |
Like Custom, but does not destroy the target actor on data production |
These are set on the WaitTargetData ability task and control when the target actor sends its data back.