Log Detail

vampire-like Git 变更总结

拆分EnemyManager的职责完成重构,修复并发时序问题,调整实体组配置并清理冗余文件

2026/06/18 basil/vampire-like commit: b6a13b18..fbc7e664

EnemyManager重构并发安全修复配置调整

basil/vampire-like 开发日志(别名:vampire-like)

本次改动概览

本次共提交6个代码类commit,全部围绕EnemyManager模块的重构与优化展开,总代码增删为 +383 / -229 行,所有改动均集中在Assets目录下的游戏核心逻辑与场景配置。

核心工作内容

模块重构(职责拆分)

  1. 刷怪位置策略抽象 把原来硬编码在EnemyManager中的随机圆形刷怪逻辑抽离为独立的ISpawnPositionStrategy接口,默认保留原逻辑实现为RandomCircleSpawnStrategy类。EnemyManager不再依赖具体的刷怪位置计算逻辑,只需要持有策略接口实例调用即可,后续如果要新增定点刷怪、波次指定位置刷怪等规则,只要实现新的策略类就行,不用修改EnemyManager的核心代码。

  2. 敌人管理职责拆分 抽离独立的EnemyRegistry类,承接原EnemyManager中所有敌人的注册、注销、存储、查询逻辑,原Manager内的敌人列表、ID索引字典等字段全部迁移到该类中。把敌人生命周期管理的基础能力和刷怪调度逻辑拆开,后续要调整敌人的存储结构、新增查询规则时,只需要修改Registry类,不会影响其他逻辑。

  3. 刷怪调度逻辑拆分 抽离独立的EnemySpawnScheduler类,承接原EnemyManager中的刷怪计时、速率控制、生成调度等逻辑,EnemyManager只需要持有调度器实例触发刷怪流程即可。后续要做动态调整刷怪速率、异步预生成敌人等需求时,都可以在调度器内独立迭代。

  4. 统一清理入口封装 把EnemyManager中直接调用_enemyRegistry.Clear()的逻辑封装为公共的ClearEnemies()方法,统一敌人清理的入口,后续如果要新增清理的前置/后置逻辑(比如清空调度器的待生成队列、触发清理回调),只需要修改这一处即可,不用调整所有调用点。

优化与问题修复

  1. 并发安全与时序问题修复 之前测试关卡切换流程时发现了时序bug:关卡结束需要隐藏所有敌人时,部分敌人已经触发了ShowEntityAsync异步加载但还未完成实例化,这时候直接清理敌人列表会出现漏处理、状态错乱的问题。 本次修复针对这个场景做了两处调整:一是给所有敌人的异步加载操作绑定了UniTask的CancelToken,异步操作完成后先判断当前上下文是否已经被取消,再执行后续逻辑;二是把EnemyRegistry对外暴露的敌人集合从可写的List<EntityBase>改为只读的IReadOnlyCollection<EntityBase>,避免外部代码意外修改内部集合引发异常,同时补充了线程安全的访问支持。

  2. 实体组配置调整 修改了Launcher.unity场景中的UGF EntityGroup配置:将Enemy实体组的实例上限从原来的500调整为10000,另一项原值为60的配置同步做了调整(暂未关联特定需求,后续确认后补充说明)。 调整Enemy组上限的原因是UGF的EntityGroup对应的对象池是同组混存的:不同模型、不同逻辑的敌人都会归在Enemy这个组的对象池中,原来的500上限冗余不足,容易出现某类敌人需要批量生成时对象池空间不足的问题,拉到10000是为了留足缓冲空间。

  3. 冗余文件清理 开发过程中临时创建ObjectBase文件夹时误提交了对应的.meta文件,确认该文件夹无用后已经删除对应的冗余meta文件。

设计思路与权衡

这次给EnemyManager做全量的职责拆分,核心原因是原来的单类承载了太多功能:刷怪策略、生成调度、敌人生命周期管理全堆在一个类里,代码越堆越厚,改任何一小块逻辑都要翻几百行,还容易影响其他不相关的功能。拆成策略、注册、调度三个独立组件之后,每个类的职责单一、边界清晰,后续要做运行时动态调控出怪策略、敌人数量管控、异步刷怪这些规划中的需求时,只要在对应的组件里迭代就行,不用动EnemyManager的核心逻辑,不管是维护还是扩展都方便很多。

目前的并发修复方案是针对当前遇到的关卡切换时序问题做的,暂时没有引入太重的线程安全机制,如果后续要加更多多线程操作敌人集合的场景(比如后台异步预加载敌人、全局数据统计),可能还要评估换用线程安全集合或者加更细粒度的锁,目前先保证现有场景的性能和稳定性。

后续关注点

  1. 重构回归验证:确认职责拆分后,刷怪逻辑、敌人增删、关卡切换等核心流程没有引入回归bug,重点检查跨组件的调用有没有漏改的情况。
  2. 并发方案验证:测试极端场景下的关卡切换(比如大量敌人异步加载时触发切关卡),确认CancelToken的逻辑覆盖了所有异步流程,不会出现状态错乱的问题。后续如果新增多线程操作敌人集合的需求,再评估是否要优化线程安全机制。
  3. 架构合理性验证:后续做动态刷怪策略、敌人数量动态调控等需求时,验证本次拆分的接口和组件是否足够灵活,有没有设计冗余或者边界考虑不到位的地方。
  4. 对象池内存评估:Enemy实体组上限拉到10000后,跟踪高刷怪量场景下的内存占用,评估对象池会不会占用过多内存,必要时再调整上限或者优化对象回收策略。

注:本文由模型 doubao-pro 生成(草稿与终稿同模型)。