跳到主要内容

目标选择

Guide

让卡牌文本、玩家输入与 FlowGraph 目标解析保持一致,使每条规则都只影响它的目标对象

Card Target 定义玩家输入

Editor LabelRuntime Enum玩家操作Behavior 中的预期来源
NoneCardTargetMode.None不选择单位Graph 自行决定需要单位、卡牌还是无目标
Single EnemyCardTargetMode.SingleEnemyUnit选择一个存活敌人Opponent 从 Card Context 读取已提交敌人
All EnemiesCardTargetMode.AllEnemyUnits不选择单位AllEnemies 解析全部存活敌人
SelfCardTargetMode.Self不选择单位Self 解析玩家

Single Enemy :卡牌会在 UI 提交选择前用瞄准箭头与高亮单位显示待选目标

Single Enemy 卡牌正在瞄准一个高亮的存活敌人

All Enemies :卡牌不经过这项选择,Behavior 必须解析 AllEnemies,让每个存活敌人收到文本承诺的范围效果,Meteor Strike 会因此对三个敌人同时显示相同伤害

Meteor Strike 对三个存活敌人同时结算 15 点伤害

UnitSource 从上下文解析单位

Source解析结果
Self当前 Host,玩家卡牌中是玩家,Status 中是持有者,Enemy Graph 中是当前行动敌人
OpponentPlayer Host 下是已提交的存活敌人,没有提交时回退到第一个存活敌人,Enemy Host 下是玩家
AllEnemies全部存活敌人,不包含已死亡单位
AllUnits存活玩家与全部存活敌人

治疗、护甲与自我 Buff 使用 Self,单目标卡牌对已选敌人的效果使用 Opponent,范围规则使用 AllEnemies

已连接 Target Port 覆盖 Source Field

当一个节点同时存在目标输入引脚 (Target Port)与静态目标字段(Source Field)时,系统遵循连线优先原则:

  • 引脚已连线:节点会直接采用连线传进来的数值或引用,此时静态面板中的 TargetSource 下拉框配置将自动失效
  • 引脚未连线:节点才会退回读取 TargetSource 字段中选择的默认上下文目标(如 SelfActive Unit)等

CardSource 与实时卡牌实例的解析

CardSource 用于在运行时动态获取对应的卡牌实例集合。每当有下游节点执行时,这些 Source 都会实时从当前战斗数据中读取最新状态:

Source解析结果
ThisCard当前正在结算的 CardInstance
HandPile当前手牌
DrawPile当前抽牌堆
DiscardPile当前弃牌堆
ExhaustPile当前消耗堆
AllPiles手牌、抽牌堆、弃牌堆与消耗堆的合并结果

Selector 集合的筛选

当卡牌效果不是由玩家手动指向,而是由游戏逻辑自动决定目标时,需要使用 Selector。通过连线组合,你可以对初始集合进行过滤、排序和数量截取,最终锁定具体的目标对象:

  • 过滤器 (Filter):保留符合特定条件的对象(如“伤害牌”、“带有中毒状态的敌人”)
  • 排序器 (Sort):对保留的对象进行排序(如“按费用从高到低”、“按生命值从低到高”)
  • 截取器 (Pick / Take / Random):从排序后的集合中,提取出下一个 Action 节点真正需要的精确对象(如“随机选择 1 张”、“获取前 2 个”)

下图展示了如何从抽牌堆中筛选出所有的基础攻击牌 (Basic Attack),然后随机抽取一张,并将其移入手牌的逻辑连线:

Card Piles 经过 Filter 与 Random Elements,再由 Move Cards 把一张匹配卡牌移入手牌

单位筛选同样适用此套逻辑: 例如,想要获取“生命值最低的敌人”,只需将 All Enemies 节点连入过滤存活的 Filter,再连接 HP 升序排列的 Sort,最后通过 Pick Element 节点提取首个元素,即可输出给伤害节点

空结果的“容错保护”与“设计规范”

系统的底层容错(静默执行)

FlowGraph 的内置 Action 具有“空值安全保护”机制:

  • 当 Action 解析目标时,会自动跳过不存在、已死亡或非法的对象
  • 如果最终解析出的目标集合为空(例如:试图对“所有敌人”造成伤害,但此时敌人已全部死亡),Action 将不会报错崩溃,也不会阻断后续 Graph 的执行,而是会安全地跳过并继续往下走

不要依赖“静默跳过”来传达规则

虽然程序不会报错,但如果“什么都不发生”会违背玩家的直觉,请不要用静默跳过来敷衍玩家,请遵循以下设计原则:

  1. 使用分支进行拦截 (Branch):利用 ConditionBranch(分支)判断目标是否为空。如果为空,走向另一个可见的备用效果或触发提示
  2. 文本清晰承诺:在卡牌描述中写明限制条件,不要让玩家产生误解
  3. 文案本地化规范
    • 玩家可见文本(描述栏):必须使用直观、易懂的游戏内语言。例如:“对选中的敌人造成 8 点伤害”“对所有敌人施加 2 层灼烧”
    • 严禁泄露底层代码字段:诸如 OpponentUnitSourceCardSourceCollection Operator 等程序术语仅用于编辑器连线实现,绝对不能出现在任何玩家可见的卡牌描述或UI中