提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- [一、Targeting 的作用和整体结构](#一、Targeting 的作用和整体结构)
- [二、Targeting Actor:目标选择逻辑核心](#二、Targeting Actor:目标选择逻辑核心)
- 三、核心调用流程详解
-
- [1. 技能中调用目标选择任务](#1. 技能中调用目标选择任务)
- [2. TargetActor 执行目标检测](#2. TargetActor 执行目标检测)
- [3. GA 接收目标数据并处理](#3. GA 接收目标数据并处理)
- [四、FGameplayAbilityTargetDataHandle 的结构](#四、FGameplayAbilityTargetDataHandle 的结构)
- 五、网络同步原理
- [六、扩展自定义 Targeting Actor](#六、扩展自定义 Targeting Actor)
- [七、EGameplayTargetingConfirmation 的用法](#七、EGameplayTargetingConfirmation 的用法)
- [八、实际案例:AOE 火球技能](#八、实际案例:AOE 火球技能)
- [九、Targeting 总结](#九、Targeting 总结)
- 十、常用开发建议
前言
Targeting 是 GAS(Gameplay Ability System)中决定技能目标的关键一环,尤其在复杂游戏中(如 RPG、MOBA、ARPG),精准、可扩展的目标选择逻辑至关重要。下面将从源码层、调用流程、网络同步机制等维度,系统性讲解 GAS 的 Targeting(目标选择)机制原理。
一、Targeting 的作用和整体结构
GAS 的 Targeting 主要用于:
- 技能命中判定(单体、AOE、群体等)
- 目标筛选(敌人/友军、距离范围、是否可见等)
- 传递目标信息给 GE(Gameplay Effect)应用
其架构由以下部分组成:
模块 | 作用 | 核心类 |
---|---|---|
Targeting Actor | 负责捕捉目标 | AGameplayAbilityTargetActor(及子类) |
Targeting Data | 描述目标结果 | FGameplayAbilityTargetDataHandle |
AbilityTask | 驱动流程 | UAbilityTask_WaitTargetData |
GA | 技能逻辑体 | 调用 TargetingActor 并处理结果 |
二、Targeting Actor:目标选择逻辑核心
核心类:AGameplayAbilityTargetActor
这是一个派生自 AActor 的类,主要用于目标获取与处理:
cpp
class AGameplayAbilityTargetActor : public AActor
{
FGameplayAbilityTargetingLocationInfo StartLocation;
FGameplayAbilityTargetDataHandle TargetData;
virtual void StartTargeting(UGameplayAbility* Ability);
virtual void ConfirmTargetingAndContinue(); // 确认目标选择
};
常见子类:
类名 | 用途 |
---|---|
AGameplayAbilityTargetActor_Trace | 单体射线目标 |
AGameplayAbilityTargetActor_GroundTrace | 地面位置点击 |
AGameplayAbilityTargetActor_Radius | 范围目标(圆形、扇形) |
AGameplayAbilityTargetActor_Line | 线段范围选择 |
三、核心调用流程详解
1. 技能中调用目标选择任务
在 UGameplayAbility::ActivateAbility 中:
cpp
UAbilityTask_WaitTargetData* Task = UAbilityTask_WaitTargetData::WaitTargetData(
this,
FName("Targeting"),
EGameplayTargetingConfirmation::UserConfirmed,
TargetActorClass
);
Task->ValidData.AddDynamic(this, &ThisClass::OnTargetDataReceived);
Task->Activate();
这个任务节点会:
- 生成并启动 TargetActor 实例
- 监听目标确认
- 接收 TargetDataHandle 并回调处理
2. TargetActor 执行目标检测
例如 AGameplayAbilityTargetActor_Trace:
cpp
void AGameplayAbilityTargetActor_Trace::StartTargeting(UGameplayAbility* InAbility)
{
PerformTrace(); // 射线检测
}
void AGameplayAbilityTargetActor_Trace::ConfirmTargetingAndContinue()
{
TargetData = CreateTargetData(); // 生成 TargetDataHandle
TargetDataReadyDelegate.Broadcast(TargetData); // 通知 AbilityTask
}
3. GA 接收目标数据并处理
cpp
void UMyFireballAbility::OnTargetDataReceived(const FGameplayAbilityTargetDataHandle& Data)
{
ApplyGameplayEffectToTarget(Data, DamageEffect);
}
这样,你就可以把 GE 应用到射线击中的目标了。
四、FGameplayAbilityTargetDataHandle 的结构
cpp
struct FGameplayAbilityTargetDataHandle
{
TArray<TSharedPtr<FGameplayAbilityTargetData>> Data;
};
每个 FGameplayAbilityTargetData 可以表示一个或多个目标。
常见实现类有:
类名 | 描述 |
---|---|
FGameplayAbilityTargetData_SingleTargetHit | 单个命中的 Actor(如射线击中) |
FGameplayAbilityTargetData_ActorArray | 一组目标(如范围内多个敌人) |
FGameplayAbilityTargetData_LocationInfo | 只包含位置(用于投掷或落点类技能) |
每种类型都实现了:
cpp
virtual UScriptStruct* GetScriptStruct() const override;
virtual AActor* GetTargetActor() const;
五、网络同步原理
Targeting 是客户端感知/服务器权威机制的典范,重点在于:
权威设计:
- 客户端只捕捉目标(如射线)
- 目标数据由客户端发给服务器
- 服务器验证目标合法性后决定是否继续技能执行
具体流程:
- 客户端生成 FGameplayAbilityTargetDataHandle
- 调用 AbilitySystemComponent->ServerSetReplicatedTargetData(...)
- 服务端在 GA 实例中收到数据,执行 GE 应用等逻辑
- 服务端同步 GE 给所有客户端
这保证了:
- 响应快速(客户端立刻看到目标)
- 安全性强(目标由服务器决定是否成立)
六、扩展自定义 Targeting Actor
你可以自定义 AGameplayAbilityTargetActor,实现以下行为:
- 自定义鼠标点击选中单位
- 选择地面落点
- 选中多个敌人后排序
- 绘制技能范围显示圈等 UI
例如:
cpp
class ATargetActor_SelectGroundLocation : public AGameplayAbilityTargetActor
{
virtual void Tick(float DeltaSeconds) override;
virtual void ConfirmTargetingAndContinue() override;
virtual void CancelTargeting() override;
};
七、EGameplayTargetingConfirmation 的用法
Targeting Actor 什么时候发出"我选好了目标"是由以下 enum 控制的:
cpp
enum class EGameplayTargetingConfirmation : uint8 {
Instant, // 自动确认(如自动锁定敌人)
UserConfirmed, // 玩家按下确认键
Custom, // 你在代码中手动调用 ConfirmTargetingAndContinue
};
八、实际案例:AOE 火球技能
-
使用 AGameplayAbilityTargetActor_GroundTrace
玩家点击地面位置
记录为火球落点坐标
-
创建 FGameplayAbilityTargetData_LocationInfo
存储落点位置(非 Actor)
-
在 OnTargetDataReceived 中:
查找落点半径内敌人
构建 FGameplayAbilityTargetData_ActorArray
应用伤害 GE 到所有命中的敌人
九、Targeting 总结
模块 | 作用 |
---|---|
AGameplayAbilityTargetActor | 提供目标选择逻辑(可自定义) |
UAbilityTask_WaitTargetData | 执行选择流程 + 网络处理 |
FGameplayAbilityTargetDataHandle | 存储目标数据,支持多种目标类型 |
GA | 在回调中处理结果,应用 GE |
网络同步 | 客户端选择,服务端验证执行,保障安全性 |
十、常用开发建议
场景 | 建议 |
---|---|
单体技能 | 用 Trace 类 TargetActor |
地面投掷类 | 自定义 TargetActor 或用 GroundTrace |
群体技能 | 使用 AOE + GetOverlappingActors 生成目标数组 |
需要自定义指示器 | 自定义 TargetActor 并与 Widget 结合 |
想预览命中效果 | 客户端先预渲染圈、特效,再提交 |