敌人创作
定义敌人的身份、HP 范围、预制体,以及选择并结算意图的行为图
Squire 已经带着 Iron Resolve 进入 The Threshing Field,同一场战斗中的 Strawman 则由一份 GameEnemyUnit 定义,它把敌人名称、Tier、Tags、HP 范围、战斗预制体和 Behavior 保存在一起
先确认当前场景的 GameCardManager 已启用至少一个 Enemy Unit Database,数据库配置决定 Game Card Editor 能够列出、创建和编辑哪些敌人
打开 Game Card Editor
Tools > TinyGiants > GCS > Game Card Editor
在窗口顶部选择 Enemy,再从左侧定位 Strawman
上图呈现了 Enemy 模式围绕 Strawman 建立的完整创作视图,左侧 List 决定当前编辑对象,中间 Inspector 保存身份、战斗预制体、14–18 HP 与 Behavior,右侧 Preview 同步核对配置结果,Used By 则把这份敌人定义连接到引用它的遭遇战
四个区域共享当前选中的 GameEnemyUnit,因此先在 List 确认 Strawman,后面的配置、预览与引用追踪就会沿同一份数据连续展开
在 List 中确认 Strawman
Enemy 模式只会从当前 GameCardManager 已启用的 Enemy Unit Database 中读取非空敌人,切换 Database 时,当前选择与右侧工作区也会切换到对应数据库
每个列表行都会显示敌人 Icon、名称、Tier 与 HP 范围,无需打开 Inspector 即可比较同一数据库中各敌人的 Tier 与 HP 范围

PresetEnemyUnitDatabase 当前包含 16 个随包敌人,Normal、Elite、Boss 与 Summon 各 4 个,选中的 Strawman 在列表中显示 Normal · HP 14–18
List 还承担当前 Enemy Unit Database 内的资产管理,具体操作与结果如下
| 操作 | 结果 |
|---|---|
| 创建 | + 创建以 NewEnemyUnit 为基名的子资产,默认使用 Normal Tier 和 20–30 HP,Name、Description、Icon、Template 与 Tags 为空,Behavior 已创建但没有节点或连接 |
| 复制 | 复制当前字段与 Behavior 并生成独立副本,子资产名追加 _Copy,显示用的 Name 暂时保持不变 |
| 删除 | − 在确认后删除当前敌人,不会保护或迁移已有引用 |
| 搜索与筛选 | 搜索和名称排序读取子资产名,Tier 使用忽略大小写的精确匹配,Tags 保留命中任一所选标签的敌人,标签比较区分大小写 |
| 排序与拖动 | 排序按钮在数据库顺序、名称升序与名称降序之间切换,拖动列表行只改变数据库中的创作顺序 |
| 批量操作 | 多选复制、批量添加或移除 Tag、批量删除,以及通过 Ctrl/Cmd+C 与 Ctrl/Cmd+V 在同类型的活动数据库之间复制 |
窗口级的选择、快捷键与批量交互见 Game Card Editor
确认列表中的 Strawman 显示 Normal · HP 14–18 后,保持它处于选中状态,先配置用于列表、界面与运行时分类的身份信息,再绑定战斗表现使用的 Icon 与 Template
定义敌人身份与战斗表现
Basic
| 字段 | 配置与使用位置 |
|---|---|
| Name | 敌人显示名称,改为非空值时会同步修改子资产名,为空时 List 与 Display 会回退显示子资产名,但 Validation 仍会报告错误 |
| Description | Display 预览与项目敌人信息界面可以读取的说明,随包 Demo 会把这段文字显示在单位悬停信息中 |
| Tier | 可选择 Normal、Elite、Boss 或当前项目中的其他标签,写入运行时 EnemyUnitState.Tier 并参与 Tier 筛选、单位属性读取和相关事件 |
| Tags | 供 List 筛选与项目逻辑使用的自由标签,FlowGraph 的 Filter 节点会区分大小写,只要单位 Tags 命中任一指定标签即可通过筛选 |
将 Name 设为 Strawman,保留说明 Burlap-stitched fieldhand.,选择 Normal Tier 并添加 Warrior Tag

Tier 本身不会自动放大 HP 或伤害,但随包 Demo 会用它调整单位缩放、位置偏移和意图高度,Tier 与 Tags 如何参与单位集合筛选见目标选择
Visual
Icon 用于 Enemy List、Display 预览和随包 Demo 的单位悬停信息,Template 则写入 GameUnit.Prefab,供编辑器 Render 与项目表现层实例化
为 Strawman 选择敌人 Avatar 与 Prefab
GCS 核心战斗状态机只创建 EnemyUnitState,不会自动生成场景对象,随包 Demo 由 BattleBoard 读取 state.Source.Prefab、实例化 Template 并绑定 UnitView
身份与表现引用确定后,Attributes 会决定每次为 Strawman 创建 EnemyUnitState 时使用的生命范围
确定进入战斗时的 HP
将 Strawman 的 HP Min 设为 14,HP Max 设为 18
运行时会在 14、15、16、17、18 五个整数中等概率选择一次,并把结果同时写入新建 EnemyUnitState 的当前 HP 与最大 HP,因此该范围的平均初始生命为 16
需要固定生命时把两项设为相同值,同一 Encounter 重复引用 Strawman 时,每个槽位仍会创建独立状态并分别随机 HP
编辑 HP Max 时,Game Card Editor 会把它限制为不低于当前 HP Min,但提高 HP Min 不会同步改写已有 HP Max,脚本或旧资产留下的反向范围也不会自动修复,Validation 会报告 HpMin > HpMax
HP 决定敌人能够承受多少伤害,Behavior 则决定它在每个敌人阶段公布哪项意图并执行什么行动
用 Behavior 规划意图并结算行动
点击 Edit FlowGraph 打开当前敌人的 Behavior,按钮下方会显示顶层 Pattern、Leaf Intent 与 Action 数量
这组摘要只统计顶层节点,Leaf Intent 会单独计数,Pattern 不含 Leaf,Action 只统计 MutatorNode,Group 内部节点不会进入摘要
Strawman 的顶层图共有 14 个节点,4 个 Group 内还包含 21 个节点,因此完整序列化规模为 35 个节点
在 FlowGraph Editor 中打开这条完整行为图
上图从 On Enemy Behavior Start 进入 Weighted Random Pattern,再把三个权重分支分别连接到一个 Leaf Intent 及其行动链,图中的可见关系对应以下运行结果
| 分支 | 权重 | 公布的意图 | 敌人阶段执行的行动 |
|---|---|---|---|
| Attack | 50 | Attack | 对玩家造成 8 点原始伤害 |
| Defend | 25 | Defend | 自身获得 8 Armor,再对玩家造成 4 点原始伤害 |
| Multi | 25 | Multi | 循环 3 次,每次对玩家造成 3 点原始伤害,共结算三次独立伤害 |
运行时只会使用 Behavior 中第一个顶层 OnEnemyBehaviorStart,并从它的 Out 开始规划
在抵达 Leaf Intent 之前,这条路径只能连续经过 Pattern,Action、状态与表现链必须位于 Leaf 之后
如果规划在抵达 Leaf 之前遇到 Action、Control、Group 或其他节点,运行时会立即停止并得到零个 Intent,当前 Validation 不会报告这项结构问题
战斗开始时,GCS 会沿这条有效的 Pattern 路径选择一个 Leaf,将 Leaf ID、Pattern 路径和意图保存在该敌人的 EnemyUnitState 中,敌人阶段会执行已经公布的同一个 Leaf,而不是再次随机
行动完成后,Sequence、Once Per Battle 与 Every N Turns 等有状态 Pattern 才会推进内部进度,敌人阶段结束后再为下一回合规划新意图,完整阶段位置见战斗循环
当前运行时每次规划会得到零个或一个 IntentEntry,其中是否包含可显示的数值,取决于 Leaf 后的线性 Out 路径
Attack、Defend 与 Heal 会沿这条路径查找第一个对应的伤害值、护甲值或正数治疗值,并将其写入意图数值,Multi、Buff、Debuff 与 Special 的意图数值保持 -1
Encounter 的 Enemy Intent Display 决定这项计划如何对外显示
| 模式 | 对外结果 |
|---|---|
Full | OnEnemyUnitIntentChanged 携带意图类别和经过相关 Hook 预估的显示数值 |
IconOnly | 事件保留意图类别,但把显示数值改为 -1 |
Hidden | 内部仍然规划并保存意图,但不发送 OnEnemyUnitIntentChanged |
CurrentIntentTag()、CurrentIntentValue() 与 PendingIntents() 读取的仍是内部原始计划,不会按上述显示模式改写,Encounter 中的完整选项见遭遇战创作
内置敌人 Pattern 还包括 Sequence Pattern、HP Threshold Pattern、Once Per Battle 与 Every N Turns,节点端口和运行规则见 Intent 节点
Strawman 用一个权重分支建立了最小完整敌人回路,更复杂的 Behavior 可以在同一个入口后继续叠加生命阈值、多个权重分支、状态和表现节点
上图中的对象已经从 Strawman 切换为 Mire Reaper,它先按 HP Threshold 选择高 HP 或低 HP 分支,再让两个 Weighted Random Pattern 分别组织 Poison、Weak、伤害与表现链路,完整可复用结构见敌人行为配方
确认这种复杂 Behavior 的扩展方式后,回到 Game Card Editor 并在 Enemy List 重新选中 Strawman,右侧 Preview 会依次呈现身份卡片、Template、入口摘要与意图构成
在 Preview 中检查编辑结果
Display
Display 会把 Icon、Name、Tier 与 Description 显示为一张敌人身份卡片,先确认 Strawman 的头像、名称、Normal 标签和说明均已显示且内容正确

Display 只证明编辑器能够读取这些字段,项目运行时 UI 是否沿用同一布局仍由自己的表现层决定,Template 则需要在 Render 中单独检查
Render
Render 会在隔离预览场景中实例化 Template,按住鼠标左键旋转,右键或中键平移,滚轮缩放,右上角按钮恢复自动取景

当前预览只确认 Prefab 能够被编辑器实例化并渲染,BattleBoard 锚点、Tier 缩放与偏移、场景排序、运行时绑定和交互组件仍需进入 Play Mode 检查
Behavior Summary
Behavior Summary 会列出 Behavior 中的顶层 Entry,并从每个 Entry 沿名为 Out 的第一条控制连接向后显示最多 8 层
OnEnemyBehaviorStart → WeightedRandomPattern 只确认入口与第一段控制链存在,摘要遇到 Pattern 分支时不会展开所有 Leaf,也不会证明某条分支可以执行到 Action
Intents
Intents 会遍历 Behavior 的顶层节点,并按 Leaf Intent 的类别和数量生成分布条
Strawman 有 Attack、Defend 与 Multi 各一个,因此预览显示三个等宽区块,这里统计的是 Leaf 数量,不是 50/25/25 权重对应的运行概率,也不会检查 Leaf 是否可达、是否连接 Action 或是否藏在 Group 内
四项 Preview 都是局部检查,真正的结构错误仍需查看当前 Enemy Unit Database 的 Issue Badge
清除 Validation 问题
Enemy 模式的 Issue Badge 扫描当前所选 Enemy Unit Database 中的全部敌人,不只统计正在查看的 Strawman
| 级别 | 触发条件 |
|---|---|
| Error | Name 为空 |
| Error | HpMin > HpMax |
| Warning | Behavior 非空且 FlowGraphValidator 返回结构问题 |
FlowGraphValidator 报告的 Behavior Warning 可以按检查对象归纳为三类
| 检查范围 | 会报告的问题 |
|---|---|
| 节点与标识 | 空或重复 NodeId、不允许用于 Enemy Host 的节点、自定义 Value 节点没有数据输出、Internal Event 或 GES Event 缺少必要标识 |
| 连接与端口 | 连接引用不存在的节点或端口、端口类型不兼容、连接元数据与输出端口不一致 |
| Group Body | 递归检查 Group 内部的同类节点、标识、连接与端口问题 |
下列内容不会进入 Validation,需要分别在 Preview、FlowGraph Editor 或 Play Mode 中确认
| 未覆盖范围 | 需要自行检查的边界 |
|---|---|
| Behavior 完整性 | Behavior 为空、缺少 OnEnemyBehaviorStart、入口未连通、Pattern 无法抵达 Leaf、Leaf 后没有 Action |
| 表现资源与说明 | 缺少 Icon 或 Template、Description 为空、Tags 为空 |
| 字段值边界 | Tier 异常、HpMin < 1 |
这些 Issue 不会阻止保存、删除或进入 Play Mode,点击 Issue 条目中的 Ping 只会定位到对应敌人、字段或 FlowGraph
结构检查完成后,再用 Used By 确认哪些活动遭遇战直接保存了当前敌人
用 Used By 回到遭遇战
Used By 只扫描当前场景 GameCardManager 已启用的 Encounter Database,并检查 GameEncounter.EnemyUnits 对当前敌人的直接引用

The Threshing Field 引用一个 Strawman,Field of Burning Effigies 引用两个 Strawman 并搭配一个 Pyre Effigy,同一 Encounter 中的重复引用仍只显示一行 Used By 结果
点击结果会切换到 Encounter 模式并定位对应资产,未启用数据库、其他场景、Prefab、代码引用、GCSApi.SummonEnemy() 与 FlowGraph 的 Summon Enemy 不在扫描范围内
打开 The Threshing Field 后,Enemy Units 会显示 Strawman 的 Normal Tier 与 14–18 HP,并保留它在敌人阵容中的槽位顺序

这项结果确认了 Encounter 对 GameEnemyUnit 的直接引用,Template、随机 HP 与 Behavior 是否真正进入战斗仍需由 Play Mode 验证
在 Play Mode 中验证 Strawman
打开随包场景 1-The Threshing Field 并进入 Play Mode,确认 Strawman 的 Template 已经生成,当前 HP 落在 14–18 范围内
画面中的 15/15 HP 是 14–18 五个可能结果中的一次有效取值,不是 Strawman 的固定生命,这次运行同时确认随包 Demo 已经加载 The Threshing Field 的敌人阵容、实例化敌人 Prefab 并绑定运行时状态
结束玩家回合后,敌人阶段会执行战斗开始时已经公布的 Leaf,随后规划下一回合意图,运行中的 HP、Armor、状态、Intent 与 Flow 执行可以在 Game Card Monitor 中检查,其余可运行场景见 Demo 场景索引
Play Mode 已经确认这份敌人定义能够进入实际战斗,项目代码需要读取同一份内容或控制运行状态时,则通过 GCSApi 接入
通过 GCSApi 读取敌人内容与运行状态
GameEnemyUnit 保存可复用的敌人定义,Encounter 中的每个非空 Enemy Units 槽位都会创建独立 EnemyUnitState,当前 HP、最大 HP、Armor、状态、死亡标记和已规划意图都保存在运行时状态中,不会回写敌人资产
GCSApi 按内容资产、当前战斗状态、意图和运行时操作提供公开入口
- 查找敌人内容:
ActiveEnemyUnitDatabases()、EnemyUnits()、FindEnemyUnit(guid) - 读取战斗单位:
AliveEnemies()、FirstAliveEnemy()、EnemyCount()、AllUnits()、Hp()、MaxHp()、Armor()、HpPercent()、IsAlive()、IsDead() - 读取当前意图:
CurrentIntentTag()、CurrentIntentValue()、PendingIntents() - 修改敌人状态:
DealDamage()、LoseHp()、Heal()、SetHp()、GainArmor()、LoseArmor()、SetArmor()、KillUnit()、ReviveUnit()、ApplyStatus()、RemoveStatus()、ModifyStatusStacks() - 运行时召唤:
SummonEnemy(GameEnemyUnit enemy, UnitState summoner = null) - 监听敌人流程:
OnEnemyTurnStarted()、OnEnemyUnitIntentChanged()、OnEnemyUnitSummoned()、OnEnemyPhaseChanged()、OnUnitHpChanged()、OnUnitDied()
OnEnemyUnitActing 当前没有独立的强类型快捷方法,需要通过通用的 Subscribe<TArgs>(),并传入 GCSEventNames.OnEnemyUnitActing 与 Action<EnemyUnitActingEventArgs> 完成订阅
当 GCSApi.Manager 非空时,EnemyUnits() 每次调用都会新建列表并汇总已启用数据库中的敌人,频繁读取时应当缓存结果
没有活动战斗时,AliveEnemies()、AllUnits() 与 PendingIntents() 返回空集合,FirstAliveEnemy() 返回 null,EnemyCount() 返回 0
CurrentIntentTag(state) 与 CurrentIntentValue(state) 不依赖当前是否仍有活动战斗,它们会继续读取传入的 EnemyUnitState,只有 state 为 null 或不是敌人状态时才返回 Unknown 与 -1
各入口的参数、返回值与调用时机见 GCSApi 使用指南,意图与阶段事件的载荷见事件使用指南
Strawman 的 Attack、Defend 与 Multi 现在已经能够在 The Threshing Field 中完成规划与执行
Mire Reaper 图中的 Poison 与 Weak 则需要用 Status 把单次行动延长为跨回合规则,在 Game Card Editor 顶部切换到 Status,按状态创作继续定义这些持续效果