跳到主要内容

战斗启动

Guide

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

选择固定或动态入口

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

配置 Bootstrap 自动启动

GameCardEncounterBootstrapDefault 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.IsWaitingForRewardtrue 时提交一次 ApplyRewardSkipReward,否则胜利流程不会发出最终的 OnBattleEnded

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

  1. 在调用 StartBattle 前订阅 OnBattleStartedOnBattleEnded 及所需的起手事件
  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 代替中止处理,它虽然会清理旧状态机,却不会补发旧战斗的结束事件,应先完成项目侧交接,再启动下一场,避免地图状态与战斗状态脱节

启动检查清单

  • 场景中只有一个处于启用状态的 GameCardManagerGCSApi.IsReady 返回 true

  • 固定场景已选择 Default Encounter 并开启 Auto Start On Play

  • 动态流程已关闭 Auto Start On Play,由项目代码持有 activeEncounter 并调用 GCSApi.StartBattle

  • 需要接收 OnBattleStarted 或起手 OnCardDrawn 的对象已在启动前订阅,并在对象禁用时释放所有订阅句柄

  • 多场 Run 在第一场战斗前初始化 Master Deck,每个 Encounter 的 StartingDeckRewardDeck 都能解析其中的卡牌

  • 胜利路径只提交一次 GCSApi.ApplyRewardGCSApi.SkipReward,并在首次点击后禁用奖励按钮,再等待 OnBattleEnded

  • 中止路径会主动恢复地图、记录结果并清理 activeEncounter

完成启动入口、生命周期与 Run 状态的连接后,进入战斗场景设置,把 Manager、战场、手牌、HUD 与表现对象组装成可运行的战斗场景