Targeting Preset 数据资产与 Task 配置参考
February 24, 2025About 7 min
Targeting Preset 数据资产与 Task 配置参考
本文是 Gameplay Targeting System 系列 的第二篇。
重点讲清楚:
UTargetingPreset到底长什么样、各种 Task 的可配参数表、几个最常用的"预设模板"配置,以及配置时的常见错误。
1. UTargetingPreset 的结构
UTargetingPreset 继承自 UDataAsset,是整个系统的配置核心。资产类型在编辑器中显示为 Targeting Preset,主面板就是一个有序数组 Targeting Task Set → Tasks。
几个不要踩的细节:
- 顺序至关重要:先选择、再过滤、最后排序。排序如果出现在过滤之前,后面再过滤掉一个目标会让排序前功尽弃。
- 每个 Task 都是
UTargetingTask的实例(EditInlineNew),直接内嵌在 DataAsset 里,不需要单独创建 Task 资产。 - 同类型 Task 可以重复添加:叠加两个过滤、加两段排序都是合法的。
2. Task 参数完整参考
2.1 选择任务(Selection)
UFW_TargetingSelectionTask_AOE(最常用)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ShapeType | ETargetingAOEShape | Box | Box / Cylinder / Sphere / Capsule / SourceComponent |
CollisionChannel | ECollisionChannel | — | 碰撞通道(与 ObjectTypes 二选一) |
CollisionObjectTypes | TArray<EObjectTypeQuery> | — | 对象类型列表(推荐用此,语义更清晰) |
HalfExtent | FVector | (0,0,0) | Box/Cylinder 半尺寸(厘米) |
Radius | FScalableFloat | 0 | Sphere/Capsule 半径(厘米) |
HalfHeight | FScalableFloat | 0 | Capsule 半高(厘米) |
DefaultSourceOffset | FVector | (0,0,0) | 中心点相对于 SourceActor 的偏移 |
bUseRelativeOffset | bool | false | true = 偏移跟随角色朝向旋转 |
bIgnoreSourceActor | bool | false | 忽略 SourceActor 自身 |
bIgnoreInstigatorActor | bool | false | 忽略 InstigatorActor |
bTraceComplex | bool | false | 复杂碰撞(贵但更精确) |
ComponentTag | FName | NAME_None | SourceComponent 模式时按 Tag 找形状组件 |
UFW_TargetingSelectionTask_TraceExt(扩展追踪)
继承自 UTargetingSelectionTask_Trace,额外支持等级缩放与接口动态参数。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
TraceType | ETargetingTraceType | Line | Line / Sphere / Capsule / Box |
TraceChannel | ETraceTypeQuery | — | 碰撞通道 |
DefaultTraceLength | FScalableFloat | 10 | 射线长度(厘米) |
DefaultSweptTraceRadius | FScalableFloat | 10 | 球体/胶囊扫描半径 |
bIgnoreSourceActor | bool | false | 忽略 Source Actor |
bComplexTrace | bool | false | 复杂碰撞 |
bUseContextLocationAsSourceLocation | bool | false | 通过接口拿动态起点 |
bTraceLengthLevel | bool | false | 追踪长度随等级缩放(通过接口) |
bSweptTraceRadiusLevel | bool | false | 半径随等级缩放 |
UFW_TargetingSelectionTask_PlayerCameraTrace
从玩家摄像机位置沿相机前向发射追踪,继承 TraceExt 的全部参数。摄像机锁定系统的标配。
2.2 过滤任务(Filter)
UFW_TargetingFilterTask_GenericTeamAttitude(队伍态度)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
DetectionByAffiliation.DetectEnemies | bool | false | 是否保留敌方 |
DetectionByAffiliation.DetectFriendlies | bool | false | 是否保留友方 |
DetectionByAffiliation.DetectNeutrals | bool | false | 是否保留中立 |
bLookController | bool | false | 通过 Controller 获取队伍 ID(玩家必须开启) |
bUseInstigator | bool | false | 以 Instigator 为基准判断敌我 |
bInvert | bool | false | 反转过滤逻辑 |
最常见配置(玩家近战找敌人):
DetectEnemies = true
bLookController = true
bUseInstigator = false
UFW_TargetingFilterTask_TagQuery(GameplayTag 过滤)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
TagQuery | FGameplayTagQuery | — | Tag 查询(Any/All/None 复合) |
bLookingForTagAssetInterface | bool | false | 通过 IGameplayTagAssetInterface 取标签(非 ASC 对象用) |
bInvert | bool | false | 反转 |
例:排除所有"死亡"目标——TagQuery = "None Of: {State.Dead}"。
UFW_TargetingFilterTask_Distance(距离过滤)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
MinDistance | FScalableFloat | 0 | 小于此距离的被过滤 |
MaxDistance | FScalableFloat | 0 | 大于此距离的被过滤(0 = 不限) |
XYZMask | FVector | (1,1,1) | 轴向掩码,(1,1,0) 只算水平距离 |
bInvert | bool | false | 反转 |
UFW_TargetingFilterTask_Obstacle(视线障碍)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
TraceChannel | ECollisionChannel | Visibility | 射线检测通道 |
CollisionProfileName | FCollisionProfileName | — | 与 Channel 二选一 |
bComplexTrace | bool | false | 复杂碰撞 |
DefaultSourceOffset | FVector | (0,0,0) | 起点偏移(一般给一个眼睛高度 Z+90) |
DefaultTargetOffset | FVector | (0,0,0) | 终点偏移 |
bInvert | bool | false | 反转:只保留被遮挡目标(罕用) |
UFW_TargetingFilterTask_TraceObstacle(球形扫描障碍)
比线性视线检测宽松一点,适合用在"目标边缘也算可见"的场景。
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ObstacleTypes | TArray<EObjectTypeQuery> | — | 哪些对象算障碍 |
ObstacleTraceSphereRadius | float | 22.0 | 扫描球半径 |
bComplexTrace | bool | false | 复杂碰撞 |
bDebug | bool | false | 显示调试线(推荐开发期开) |
bUseInstigator | bool | false | 从 Instigator 位置发起 |
bInvert | bool | false | 反转 |
UTargetingFilterTask_ActorClass(引擎原生,按类过滤)
| 参数 | 类型 | 说明 |
|---|---|---|
RequiredActorClassFilters | TArray<UClass*> | 白名单 |
IgnoredActorClassFilters | TArray<UClass*> | 黑名单 |
2.3 排序任务(Sort)
UFW_TargetingSortTask_SortByUtilityScore(效用函数排序)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
bAscending | bool | false | false = 分数高排前 |
UtilityScoreFragmentInstances | TArray<UFragment*> | — | 效用片段数组(可叠加) |
效用片段 UFW_Targeting_UtilityScoreFragment_Distance:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Weight | float | 1.0 | 权重(可为负) |
bClamp | bool | false | 钳制到 [ClampMin, ClampMax] |
bNormalize | bool | false | 在本次候选集中归一化 |
bReverseNormalize | bool | false | 反向归一化(近的更高分) |
bUseDistanceToNearestBlockingCollider | bool | false | 用碰撞体边缘距离而非 Actor 原点距离 |
UTargetingFilterTask_SortByDistance(引擎原生)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
bAscending | bool | true | true = 近的排前面 |
bUseDistanceToNearestBlockingCollider | bool | false | 同上 |
3. 常用预设模板
下面四个模板拿来直接参考调整就行。所有 Radius 单位都是 cm。
模板 A:近战锁敌(球形 AOE + 敌方 + 视线 + 距离排序)
[0] UFW_TargetingSelectionTask_AOE
ShapeType = Sphere
CollisionObjectTypes = [Pawn]
Radius = 800
bIgnoreSourceActor = true
DefaultSourceOffset = (0, 0, 50) // 从腰部高度扫描
[1] UTargetingFilterTask_ActorClass
RequiredActorClassFilters = [AGameCharacter]
[2] UFW_TargetingFilterTask_GenericTeamAttitude
DetectEnemies = true
bLookController = true
[3] UFW_TargetingFilterTask_TagQuery
TagQuery = "None Of: {State.Dead}"
[4] UFW_TargetingFilterTask_Obstacle
TraceChannel = Visibility
DefaultSourceOffset = (0, 0, 90) // 眼睛高度
[5] UFW_TargetingSortTask_SortByUtilityScore
bAscending = false
Fragments:
[0] UFW_Targeting_UtilityScoreFragment_Distance
Weight = 1.0
bNormalize = true
bReverseNormalize = true // 近的分数高
模板 B:投射物一次性命中扩散(小球形 AOE)
[0] UFW_TargetingSelectionTask_AOE
ShapeType = Sphere
CollisionObjectTypes = [Pawn, WorldDynamic]
Radius = 50
bIgnoreInstigatorActor = true // 不打自己人的发射者
[1] UFW_TargetingFilterTask_GenericTeamAttitude
DetectEnemies = true
bUseInstigator = true // 以飞行物的发射者判断敌我
[2] UFW_TargetingFilterTask_TagQuery
TagQuery = "None Of: {State.Dead}"
[3] UTargetingFilterTask_SortByDistance
bAscending = true // 最近的排第一
模板 C:摄像机锁定(相机方向追踪 + 屏幕中心优先)
[0] UFW_TargetingSelectionTask_PlayerCameraTrace
TraceType = Sphere
DefaultTraceLength = 3000
DefaultSweptTraceRadius = 150
TraceChannel = Visibility
bIgnoreSourceActor = true
[1] UFW_TargetingFilterTask_GenericTeamAttitude
DetectEnemies = true
bLookController = true
[2] UFW_TargetingFilterTask_TagQuery
TagQuery = "None Of: {State.Dead}"
[3] UFW_TargetingFilterTask_RecentlyRendered
RecentlyRenderedTime = 0.5 // 0.5s 内被渲染过才允许锁定
模板 D:奥义观众查找(范围内所有存活角色,近的优先)
[0] UFW_TargetingSelectionTask_AOE
ShapeType = Sphere
CollisionObjectTypes = [Pawn]
Radius = 1000
bIgnoreSourceActor = true
[1] UTargetingFilterTask_ActorClass
RequiredActorClassFilters = [AGameCharacter]
[2] UFW_TargetingFilterTask_TagQuery
TagQuery = "None Of: {State.Dead}"
[3] UTargetingFilterTask_SortByDistance
bAscending = true
4. 配置 Tips 与常见错误
4.1 几个反复踩坑的点
CollisionChannel与CollisionObjectTypes互斥:编辑器允许都填,但运行时只生效一个。优先用CollisionObjectTypes,意图更清晰。bInvert改的是"是否保留"的语义:不是"是否参与过滤"。配错的话整个过滤反着来。FScalableFloat不用等级缩放就直接填一个常数。CurveTable 仅在需要等级缩放时使用。- 同一个 Preset 资产在不同 Source 之间是共享的:不要在 Task 上挂运行时数据,所有动态数据都应放在
FTargetingSourceContext或通过接口传入。
4.2 常见错误对照表
| 错误现象 | 可能原因 | 解决方法 |
|---|---|---|
| 查询结果总是空 | CollisionObjectTypes 没包含目标的对象类型 | 确认目标 Actor 的 Object Type,把对应项加进来 |
| 把 SourceActor 自己也选中了 | 没开 bIgnoreSourceActor | 勾上 |
| 过滤完全没目标 | bInvert 误开 / TagQuery 写反 | 检查反转开关 |
| 近战目标总选错人 | 缺视线过滤或没配排序 | 加 Obstacle + 距离排序 |
投射物的 OneTimeTargetingPreset 不生效 | 软引用未加载或路径错 | 确认资产被加载、路径正确 |
| 异步请求结果在回调前读取 | 在 StartAsync 后立即读 | 必须在 CompletionDelegate 回调里读 |
| 句柄/数据泄漏 | 没设 bReleaseOnCompletion 也没手动 Release | 设 bReleaseOnCompletion = true 或调用 ReleaseTargetRequestHandle |
4.3 调试小技巧
UFW_TargetingFilterTask_TraceObstacle把bDebug打开,会画出每个被检测的"Source → Target"路径,绿色未挡、红色被挡。- 框架层的子系统通常提供
GetFilteredOutResults(Handle)之类的接口,能列出"哪些目标在哪个过滤步骤被踢掉的",是调试 Preset 的利器。 - 资产命名建议遵循统一前缀,例如
DA_TargetingPreset_<角色>_<用途>或DA_TP_<功能>,方便资产浏览器搜索。
5. 创建一个新 Preset 的步骤
- Content Browser → 右键 → Miscellaneous → Data Asset → 选择
TargetingPreset。 - 命名,按上面的命名规范。
- 打开资产,在
Targeting Task Set → Tasks里依次点+,按 Selection → Filter → Sort 顺序添加 Task,逐个展开配参数。 - 在 PIE 里跑一遍,开启 Task 的
bDebug(如果支持)观察范围;用LogTargetingSystem Verbose看命中数量。
下一篇看 C++ API 与自定义任务,或直接跳到 蓝图使用。