Gameplay Targeting System 蓝图使用指南
Gameplay Targeting System 蓝图使用指南
本文是 Gameplay Targeting System 系列 的第四篇。
讲清楚:蓝图里可用的所有节点、三种典型场景的连线(摄像机锁定 / GAS 能力 / 普通 Actor),以及如何在蓝图里写自定义 Task。
1. 可用节点速览
系统在蓝图里暴露了四组节点。
1.1 同步执行节点
节点: Execute Targeting Request(UTargetingSubsystem 上)
| 引脚 | 说明 |
|---|---|
Targeting Preset | UTargetingPreset*(必填) |
In Source Context | FTargetingSourceContext(必填) |
Completion Dynamic Delegate | 完成回调 |
同帧内完成所有任务,适合低复杂度查询,不返回 Handle——结果需要在回调里读。
1.2 异步执行节点
节点: Start Async Targeting Request
| 引脚 | 说明 |
|---|---|
Targeting Preset | UTargetingPreset* |
In Source Context | FTargetingSourceContext |
Completion Dynamic Delegate | 完成回调 |
| 返回值 | FTargetingRequestHandle(用于取消/读取结果) |
分帧执行,异步 Trace 由物理线程处理,不会卡顿。
1.3 异步 Action 节点(蓝图首选)
节点: Perform Targeting Request / Perform Filtering Request
(来自 UAsyncAction_PerformTargeting)
| 输出引脚 | 说明 |
|---|---|
Targeted | 目标就绪时触发的执行引脚(含 Handle) |
Async Task Ref | 异步任务引用,需要时调用 Cancel |
这是蓝图里最舒服的写法:节点自带 await 式输出引脚,自动管理生命周期。
1.4 GAS 能力任务节点
节点: Perform Targeting Request(来自 UAbilityTask_PerformTargeting,只能在 Ability 蓝图里使用)
| 引脚 | 说明 |
|---|---|
In Targeting Preset | UTargetingPreset* |
Allow Async | 是否允许异步 |
On Target Ready | 输出引脚,目标就绪时触发(含 Handle) |
1.5 结果读取节点
拿到 Handle 之后用:
| 节点 | 返回 |
|---|---|
Get Targeting Results Actors | TArray<AActor*>,已按 Preset 排序,[0] 是最优 |
Get Targeting Results | TArray<FHitResult>,需要位置/法线/组件时用 |
Get Targeting Source Context | 取回当时的 SourceContext |
1.6 辅助节点
Get Targeting Subsystem:从 WorldContextObject 获取子系统。Remove Async Targeting Request With Handle:取消进行中的异步请求。Override Collision Query Task Data:运行时改碰撞忽略列表。
2. 三种典型流程
2.1 同步执行
2.2 异步 Action(推荐)
2.3 GAS 能力内
3. 场景一:摄像机锁定
锁定一般拆成两段:
- 按下锁定键时执行一次"找最优锁定目标"。
- 锁定中每 ~0.2 秒做一次"验证当前目标是否仍然有效",无效就解锁/切换。
锁定查找 Preset 典型配置(与 DataAssets 模板 C 对应):
[0] UFW_TargetingSelectionTask_PlayerCameraTrace
ShapeType = Sphere
DefaultTraceLength = 3000
DefaultSweptTraceRadius = 150
[1] UFW_TargetingFilterTask_GenericTeamAttitude
DetectEnemies = true
bLookController = true
[2] UFW_TargetingFilterTask_Obstacle
TraceChannel = Visibility
[3] UFW_TargetingSortTask_SortByUtilityScore
UtilityScoreFragments:
[0] Distance(Weight=0.5, bNormalize=true, bReverseNormalize=true)
蓝图侧伪代码:
Event OnLockOnPressed:
→ Get Targeting Subsystem
→ Make Targeting Source Context (Source=Player, Instigator=Player)
→ Execute Targeting Request (DA_LockOn, Context)
→ On Complete:
→ Get Targeting Results Actors (Handle)
→ if Actors.Num > 0:
→ Set CurrentLockTarget = Actors[0]
→ Start LockOn Tick
Event LockOnTick (每 0.2 秒):
→ if CurrentLockTarget == null: Stop Tick
→ Execute Targeting Request (DA_LockOn_CheckValid, Context)
→ On Complete:
→ Get Targeting Results Actors
→ if 不包含 CurrentLockTarget:
→ Clear CurrentLockTarget
注意 bLookController 必须开,玩家的队伍 ID 是挂在 PlayerController 上的。
4. 场景二:GAS 能力中执行目标查找
技能释放时通过 Perform Targeting Request AbilityTask 选目标,然后对目标施加 GameplayEffect。
Event ActivateAbility:
│
├→ [Perform Targeting Request (AbilityTask)]
│ Targeting Preset = DA_TargetingPreset_MySpell
│ Allow Async = true
│
└→ [On Target Ready]
├→ [Get Targeting Subsystem (self)]
├→ [Get Targeting Results Actors (Handle)] → Targets
└→ [For Each Target]
└→ [Apply Gameplay Effect to Target]
GameplayEffect = GE_Damage_MySpell
Level = AbilityLevel
└→ [End Ability]
奥义观众查找 Preset(参考 DataAssets 模板 D):
[0] UTargetingSelectionTask_AOE (Sphere, Radius=800)
[1] UTargetingFilterTask_ActorClass (Required = [AGameCharacter])
[2] UFW_TargetingFilterTask_TagQuery (None Of: {State.Dead})
[3] UTargetingFilterTask_SortByDistance (bAscending = true)
5. 场景三:普通 Actor 蓝图
Boss 行为蓝图这类不走 GAS 的逻辑,用 Perform Targeting Request 异步 Action 最干净。
Event OnBossPhase2Start:
│
├→ [Perform Targeting Request (AsyncAction)]
│ Source Actor = Self
│ Targeting Preset = DA_TP_BurstSprint_Explosion
│ Use Async Targeting = true
│
└→ [Targeted]
Handle → 变量
├→ [Get Targeting Subsystem]
└→ [Get Targeting Results Actors]
→ For Each Actor:
→ Spawn Explosion FX at Actor Location
Boss 场景一类 Preset 还经常会查"附近可交互对象"(可吹飞的车、可跳上去的车、最近的鸟群控制器),思路一致——为每种意图建一个 Preset,由 Boss 的目标组件在合适时机各自调用。
6. 蓝图自定义 Task
蓝图侧的自定义 Task 三个父类:
USimpleTargetingSelectionTask— 选择,事件SelectTargets,可用Add Target Actor/Add Hit Result。USimpleTargetingFilterTask— 过滤,事件ShouldRemoveTarget,返回true表示移除。USimpleTargetingSortTask— 排序,事件GetScoreForTarget,返回分数。
6.1 蓝图选择任务示例
Event SelectTargets (Handle, SourceContext):
├→ [Get All Actors Of Class] → AGameCharacter
└→ [For Each Actor]
└→ [Branch: Is Actor Alive?]
│ True
└→ [Add Target Actor (Handle, Actor)]
6.2 蓝图过滤任务示例
Event ShouldRemoveTarget (Handle, TargetData) → ReturnValue(bool):
├→ [Get Actor from HitResult] = Target
├→ [Get Distance (Self.Location, Target.Location)]
└→ [Return: Distance > 1000] // 超过 10m 移除
6.3 蓝图排序任务示例(屏幕中心优先)
Event GetScoreForTarget (Handle, TargetData) → ReturnValue(float):
├→ [Get Actor from HitResult] = Target
├→ [Get Dot Product (PlayerForward, DirectionToTarget)]
└→ [Return: DotProduct] // 越在正前方分数越高
7. 节点字段速查
7.1 Make Targeting Source Context
| 字段 | 必填 | 典型填法 |
|---|---|---|
Source Actor | 是 | 发起者(玩家 / 飞行物) |
Instigator Actor | 否 | 最终责任方(控制飞行物的玩家) |
Source Location | 否 | 留 (0,0,0) 自动取 SourceActor 位置 |
Source Socket Name | 否 | 指定骨骼插槽作为起点(如 Muzzle) |
Source Object | 否 | 自定义任务可读的额外对象 |
7.2 Get Targeting Results Actors
- 输入:
Targeting Handle(来自回调引脚) - 输出:
TArray<AActor*>,已按 Preset 排序,[0] 是最优
必须在完成回调里调用,提前读取拿不到结果。
7.3 Get Targeting Results
- 输入:
Targeting Handle - 输出:
TArray<FHitResult>,每条包含 Actor、Component、Location、Normal、Distance
需要命中位置(生成 VFX、计算飞溅方向)时用这个,而不是 Get Targeting Results Actors。
8. 几个蓝图侧的坑
- 结果引脚没值 —— 多半是没接对 Handle,或在回调外读结果。
- 多次按锁定键导致重叠请求 —— 异步请求一定要保存
Async Task Ref,发新请求前先取消旧的。 - Source Actor 留空 —— Task 会在第一步就拿不到位置,结果集为空。
- 不要在 Tick 里同步执行 —— 高频同步请求是性能瓶颈的常见原因,必要时改异步或延长间隔。
下一篇:性能、调试、维护清单。