虚幻GAS底层原理解剖六 (Target)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • [一、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 主要用于:

  1. 技能命中判定(单体、AOE、群体等)
  2. 目标筛选(敌人/友军、距离范围、是否可见等)
  3. 传递目标信息给 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();

这个任务节点会:

  1. 生成并启动 TargetActor 实例
  2. 监听目标确认
  3. 接收 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 是客户端感知/服务器权威机制的典范,重点在于:

权威设计:

  1. 客户端只捕捉目标(如射线)
  2. 目标数据由客户端发给服务器
  3. 服务器验证目标合法性后决定是否继续技能执行

具体流程:

  1. 客户端生成 FGameplayAbilityTargetDataHandle
  2. 调用 AbilitySystemComponent->ServerSetReplicatedTargetData(...)
  3. 服务端在 GA 实例中收到数据,执行 GE 应用等逻辑
  4. 服务端同步 GE 给所有客户端

这保证了:

  1. 响应快速(客户端立刻看到目标)
  2. 安全性强(目标由服务器决定是否成立)

六、扩展自定义 Targeting Actor

你可以自定义 AGameplayAbilityTargetActor,实现以下行为:

  1. 自定义鼠标点击选中单位
  2. 选择地面落点
  3. 选中多个敌人后排序
  4. 绘制技能范围显示圈等 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 火球技能

  1. 使用 AGameplayAbilityTargetActor_GroundTrace

    玩家点击地面位置

    记录为火球落点坐标

  2. 创建 FGameplayAbilityTargetData_LocationInfo

    存储落点位置(非 Actor)

  3. 在 OnTargetDataReceived 中:

    查找落点半径内敌人

    构建 FGameplayAbilityTargetData_ActorArray

    应用伤害 GE 到所有命中的敌人

九、Targeting 总结

模块 作用
AGameplayAbilityTargetActor 提供目标选择逻辑(可自定义)
UAbilityTask_WaitTargetData 执行选择流程 + 网络处理
FGameplayAbilityTargetDataHandle 存储目标数据,支持多种目标类型
GA 在回调中处理结果,应用 GE
网络同步 客户端选择,服务端验证执行,保障安全性

十、常用开发建议

场景 建议
单体技能 用 Trace 类 TargetActor
地面投掷类 自定义 TargetActor 或用 GroundTrace
群体技能 使用 AOE + GetOverlappingActors 生成目标数组
需要自定义指示器 自定义 TargetActor 并与 Widget 结合
想预览命中效果 客户端先预渲染圈、特效,再提交
相关推荐
伽蓝_游戏10 小时前
UGUI源码剖析(3):布局的“原子”——RectTransform的核心数据模型与几何学
ui·unity·架构·c#·游戏引擎·游戏程序·几何学
Kingsdesigner15 小时前
游戏开发流程革命:我用Substance插件,在UE5内实现材质的实时“创世纪”
游戏·adobe·ue5·游戏引擎·游戏开发·设计师·substance 3d
污领巾15 小时前
虚幻GAS底层原理解剖七 (ASC)
游戏引擎·php·虚幻
污领巾15 小时前
虚幻GAS底层原理解剖四 (TAG)
游戏引擎·虚幻
污领巾1 天前
虚幻GAS底层原理解剖二 (GE)
游戏引擎·虚幻
南無忘码至尊2 天前
Unity编辑器工具:一键为场景中所有MeshRenderer对象添加指定脚本
unity·c#·游戏引擎·游戏开发
枯萎穿心攻击2 天前
算法入门第一篇:算法核心:复杂度分析与数组基础
算法·unity·矩阵·c#·游戏引擎
王维志2 天前
Unity轻量观察相机
unity·游戏引擎
DoomGT2 天前
Physics Simulation - UE中Projectile相关事项
ue5·游戏引擎·虚幻·虚幻引擎·unreal engine