跳到主要内容

战斗启动

Guide

每次进入场景都运行同一场遭遇战时使用 Bootstrap,而由地图、任务或关卡流程动态选择遭遇战时请调用 GCSApi.StartBattle,两种入口共享同一套战斗生命周期

选择固定或动态入口​

每次进入 Play Mode 都要启动同一场战斗时,请把遭遇战保存在 GameCardEncounterBootstrap 的 Default Encounter 中,Demo 场景、独立战斗测试以及按遭遇战单独加载的场景都适合这样启动

配置 Bootstrap 自动启动​

在 GameCardEncounterBootstrap 的 Default Encounter 中选择要运行的遭遇战,保持 Auto Start On Play 开启,Inspector 顶部会显示 Ready — starts on Play

Game Card Encounter Bootstrap 中已选择 Fenmoss Hollow,状态为 Ready — starts on Play,并开启 Auto Start 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

项目协调器需要按以下顺序完成交接:

  1. 在调用 StartBattle 前订阅 OnBattleStarted、OnBattleEnded 及所需的起手事件
  2. 启动时记录 activeEncounter,切换地图与战斗画面
  3. 收到 OnBattleEnded 后保存胜负结果、清空 activeEncounter 并恢复地图
  4. 对象禁用时释放事件订阅返回的 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 与表现对象组装成可运行的战斗场景