刷怪与战斗模块 private

刷怪与战斗模块

目标

编辑器描述出生点、波次和随机模板。运行时 Battle 负责场景实体、刷怪结果和共享属性;在联网模式下,当前 Host 客户端负责已分配怪物的 AI 目标、移动和技能决策,其他客户端只表现同步结果。

编辑器数据结构

  • MonsterWaveTrapGroup:波次组以及门/屏障,子节点命名 WaveGroupId_。
  • MonsterSpawnRandomGroup:模板与 Weight 权重,预览时只激活一个子节点。
  • ObjectSpawnPoint:统一出生点,类型来自 Game.Core.ObjectType。

随机模板

[Range(0, 1)] public float Weight = 1;

void OnPreviewChanged()
{
    foreach (var t in _templates)
        t.Child.SetActive(t.Name == _preview);
}

编辑器会拒绝同名模板并刷新 _templates;运行时应读取导出 Guid/配置,不依赖预览状态。

运行时刷怪

Assets/Code/Game/OLogic/Guard/WaveSpawner.cs 使用 Walkable 区域:

int enemyMask = 1 << NavMesh.GetAreaFromName("Walkable");
float3 randomPos = default;
if (!RandomTool.RandomPointOnNavMesh(transform.position, Radius,
    enemyMask, ref randomPos)) return;
SpawnEnemy((Vector3)randomPos);

网络模式的实际顺序可以拆成两段:

Battle/场景侧:
读取地图 -> 处理触发器 -> SignalSpawn -> 创建 Monster 实体
           -> 加入 MonsterMgr -> 分配 Scene.HostPlayerId -> 广播实体/归属

Host 客户端:
收到 AddEntity + ChangeHostPlayerId
  -> ChangeControllerSystem 注入 SyncDesMoveController
  -> EnemyStateMachine.UpdateState
  -> NavMesh/MoveController/技能执行
  -> MoveBegin/StateSync/FrameStateSync 回 Battle
  -> Battle 校验并广播给其他客户端

服务端 BattleStateSync.OnUpdate() 没有独立怪物 AI Think;不要用“Battle 权威节点计算 AI”描述当前实现。

Host 控制权切换的代码关系

服务端切换 Host 时,把每个 Monster 的 playerId 写成新 Host,并发送 ChangeHostPlayerId。客户端收到后执行:

gameEntity.ControllerId = playerId;
ChangeControllerUtils.ChangeControlledType(gameEntity, coreEntity);

actorEntity.ChangeController(
    true,
    new SyncDesMoveController(
        LogicMessageType.SyncMoveData,
        item.linkedCore.Id));

actorEntity.ChangeController(
    false,
    new SyncDesDummyMoveController());

排查怪物为什么在某台客户端不动时,先查 Monster.playerId、ChangeHostPlayerId、coreEntity.playerId 和 ActorEntity.IsLocal,再查 AI 状态机和 NavMesh;不要先假设是服务端 AI 没算出来。

新增怪物

  1. 在 Assets/Code/Game/OLogic/Actor/Enemy/Concrete 新建 Controller/StateMachine。
  2. 登记 ObjectType、Prefab 映射和配置表。
  3. 将模板放入 MonsterSpawnRandomGroup 或波次组。
  4. 导出地图,在本地服确认首个快照包含实体。
  5. 测试死亡、掉落、重连和重复进图,确保不重复生成。

权威边界

行为当前项目实际负责方说明
刷怪时机/数量Battle 场景实体 + 玩法触发器Battle 创建并保存 Monster,客户端不应重复创建
AI 目标搜索/状态切换当前 Host 客户端 EnemyStateMachineHost 执行 SearchAndLockTarget、追击、攻击和技能决策
Monster 移动/技能同步Host 客户端产生,Battle 校验/转发其他客户端通过状态、移动和位置包重放
HP/死亡/掉落结算Battle客户端只做即时表现,结果以服务端为准
Host 切换Battle 选举 + 所有客户端切换控制器新 Host 接管 Monster,Battle 不在服务器接管 AI
预览模板Unity Editor不参与运行时判定