战斗启动
每次进入场景都运行同一场遭遇战时使用 Bootstrap,而由地图、任务或关卡流程动态选择遭遇战时请调用 GCSApi.StartBattle,两种入口共享同一套战斗生命周期
选择固定或动态入口
- 一个场景一场遭遇战
- 地图或流程控制
每次进入 Play Mode 都要启动同一场战斗时,请把遭遇战保存在 GameCardEncounterBootstrap 的 Default Encounter 中,Demo 场景、独立战斗测试以及按遭遇战单独加载的场景都适合这样启动
地图节点、任务状态、关卡分支或匹配结果需要动态选出遭遇战时,关闭 Bootstrap 的自动启动,再由项目流程调用 GCSApi.StartBattle(encounter)
配置 Bootstrap 自动启动
在 GameCardEncounterBootstrap 的 Default Encounter 中选择要运行的遭遇战,保持 Auto Start On Play 开启,Inspector 顶部会显示 Ready — starts on Play

进入 Play Mode 后,Bootstrap 会使用 Default Encounter 的直接引用发起战斗,Ready 只校验编辑器发现与场景配置,启动时不会再次要求该 Encounter Database 保持 Active,Encounter 已经保存的玩家、敌人、起始卡组和卡牌引用仍然有效,Active 对 Game Card Editor、选择器、GCSApi 查询及部分运行时 ID 解析的影响见数据库与内容发现
GameCardEncounterBootstrap 必须与 GameCardManager 位于同一 GameObject,添加时 Unity 会自动补上缺失的 Manager,除保存固定 Encounter 外,Bootstrap 还可以在 StartBattle 返回后触发 UnityEvent 或 GES 事件
| 字段 | 默认值 | 作用 |
|---|---|---|
Default Encounter | 空 | 进入 Play Mode 时传给 GameCardManager.StartBattle 的遭遇战 |
Auto Start On Play | 开启 | 在组件的 Start 阶段启动 Default Encounter |
Use GES Events | 关闭 | 安装 GES 后,在 UnityEvent 与 GES 事件列表之间选择 Bootstrap 输出方式 |
On Bootstrap | 空 | 未使用 GES 时,在 StartBattle 返回后调用 |
On Bootstrap Events | 空 | 使用 GES 时,在 StartBattle 返回后按列表顺序触发 |
Default Encounter 为空或当前没有可用的 Manager 时,Bootstrap 只会记录警告,不会创建战斗,表格中的输出也只属于 Bootstrap 组件,不属于通用战斗生命周期,因此,通过代码直接启动的遭遇战不会触发它们,需要把固定入口接入 GES 时可查看 GES 集成
从项目流程动态启动
Encounter 改由地图或关卡流程选出后,场景仍然保留 GameCardManager,但要关闭 Auto Start On Play,并在流程协调器中保存当前的 activeEncounter
private GameEncounter activeEncounter;
public void StartEncounter(GameEncounter encounter)
{
if (encounter == null || activeEncounter != null || !GCSApi.IsReady) return;
activeEncounter = encounter;
GCSApi.StartBattle(encounter);
}
GCSApi.IsReady 只表示场景中存在可用的 Manager,不表示上一场战斗已经完成,再次调用 StartBattle 会清理当前战斗,但不会先为旧战斗发出 OnBattleEnded
因此,只要 activeEncounter 非空,项目流程就应拒绝再次启动,胜利后的奖励等待也属于当前战斗,只有收到 OnBattleEnded 后才能清空 activeEncounter 并恢复地图
在战斗结束后接回项目流程
Bootstrap 和 GCSApi 最终都会把 GameEncounter 交给同一个 Manager,地图、HUD、结果界面与存档系统只需围绕统一生命周期工作
上图说明失败会直接进入 OnBattleEnded,胜利则会等待奖励被选择或跳过,奖励 UI 必须在 GCSApi.IsWaitingForReward 为 true 时提交一次 ApplyReward 或 SkipReward,否则胜利流程不会发出最终的 OnBattleEnded
项目协调器需要按以下顺序完成交接:
- 在调用
StartBattle前订阅OnBattleStarted、OnBattleEnded及所需的起手事件 - 启动时记录
activeEncounter,切换地图与战斗画面 - 收到
OnBattleEnded后保存胜负结果、清空activeEncounter并恢复地图 - 对象禁用时释放事件订阅返回的
IDisposable
OnBattleStarted 会在 StartBattle 调用期间发出,因此不能等启动后再订阅,完整协调器示例、事件参数和 UI 接入方式见事件使用指南与自定义 UI 集成
初始化多场 Run 的 Master Deck
Master Deck 需要在战斗之间保留,开始新 Run 时,请先清除上一局的持久状态,再按 Starting Deck 的份数创建 MasterDeckEntry,最后通过 GCSApi.SetMasterDeck 写入
Master Deck 为空时,GCS 只会为当前战斗临时使用玩家的 Starting Deck,不会把这份回退结果写回持久卡组,如果首战奖励只加入一张卡,Master Deck 中便只剩这一条记录,下一场也不会重新补入完整起始卡组
每个条目的卡牌 GUID 必须能从当前 Encounter 的 Starting Deck 或 Reward Deck 解析;无法匹配的条目会被跳过,初始化代码和后续增删、升级、费用修改见卡牌与牌堆生命周期与 GCSApi 使用指南
GCSApi.ClearMasterDeck 会一起清空旧 Master Deck 与 Run 能量加成,因此只应在开始新 Run 时调用,后续遭遇战之间保留 Master Deck,奖励、升级、移除与费用变化后的卡组结果才会继续进入下一场战斗,同时仍受上述卡牌解析范围限制
中止未完成的战斗
正常战斗都会以 OnBattleEnded 完成交接,而当玩家退出尚未结束的战斗时,系统会调用 GCSApi.DisposeBattle() 清理当前战斗状态,该接口不会发出 OnBattleEnded,也不会清空 Master Deck 或 Run 能量加成,此时地图恢复、失败判定、存档处理与 activeEncounter 清理都要由项目流程完成
不要用新的 StartBattle 代替中止处理,它虽然会清理旧状态机,却不会补发旧战斗的结束事件,应先完成项目侧交接,再启动下一场,避免地图状态与战斗状态脱节
启动检查清单
-
场景中只有一个处于启用状态的
GameCardManager,GCSApi.IsReady返回true -
固定场景已选择
Default Encounter并开启Auto Start On Play -
动态流程已关闭
Auto Start On Play,由项目代码持有activeEncounter并调用GCSApi.StartBattle -
需要接收
OnBattleStarted或起手OnCardDrawn的对象已在启动前订阅,并在对象禁用时释放所有订阅句柄 -
多场 Run 在第一场战斗前初始化 Master Deck,每个 Encounter 的
StartingDeck或RewardDeck都能解析其中的卡牌 -
胜利路径只提交一次
GCSApi.ApplyReward或GCSApi.SkipReward,并在首次点击后禁用奖励按钮,再等待OnBattleEnded -
中止路径会主动恢复地图、记录结果并清理
activeEncounter
完成启动入口、生命周期与 Run 状态的连接后,进入战斗场景设置,把 Manager、战场、手牌、HUD 与表现对象组装成可运行的战斗场景