basil/vampire-like 开发日志(别名:vampire-like)
本次改动概览
本次共提交6个代码类commit,全部围绕EnemyManager模块的重构与优化展开,总代码增删为 +383 / -229 行,所有改动均集中在Assets目录下的游戏核心逻辑与场景配置。
核心工作内容
模块重构(职责拆分)
-
刷怪位置策略抽象 把原来硬编码在EnemyManager中的随机圆形刷怪逻辑抽离为独立的
ISpawnPositionStrategy接口,默认保留原逻辑实现为RandomCircleSpawnStrategy类。EnemyManager不再依赖具体的刷怪位置计算逻辑,只需要持有策略接口实例调用即可,后续如果要新增定点刷怪、波次指定位置刷怪等规则,只要实现新的策略类就行,不用修改EnemyManager的核心代码。 -
敌人管理职责拆分 抽离独立的
EnemyRegistry类,承接原EnemyManager中所有敌人的注册、注销、存储、查询逻辑,原Manager内的敌人列表、ID索引字典等字段全部迁移到该类中。把敌人生命周期管理的基础能力和刷怪调度逻辑拆开,后续要调整敌人的存储结构、新增查询规则时,只需要修改Registry类,不会影响其他逻辑。 -
刷怪调度逻辑拆分 抽离独立的
EnemySpawnScheduler类,承接原EnemyManager中的刷怪计时、速率控制、生成调度等逻辑,EnemyManager只需要持有调度器实例触发刷怪流程即可。后续要做动态调整刷怪速率、异步预生成敌人等需求时,都可以在调度器内独立迭代。 -
统一清理入口封装 把EnemyManager中直接调用
_enemyRegistry.Clear()的逻辑封装为公共的ClearEnemies()方法,统一敌人清理的入口,后续如果要新增清理的前置/后置逻辑(比如清空调度器的待生成队列、触发清理回调),只需要修改这一处即可,不用调整所有调用点。
优化与问题修复
-
并发安全与时序问题修复 之前测试关卡切换流程时发现了时序bug:关卡结束需要隐藏所有敌人时,部分敌人已经触发了
ShowEntityAsync异步加载但还未完成实例化,这时候直接清理敌人列表会出现漏处理、状态错乱的问题。 本次修复针对这个场景做了两处调整:一是给所有敌人的异步加载操作绑定了UniTask的CancelToken,异步操作完成后先判断当前上下文是否已经被取消,再执行后续逻辑;二是把EnemyRegistry对外暴露的敌人集合从可写的List<EntityBase>改为只读的IReadOnlyCollection<EntityBase>,避免外部代码意外修改内部集合引发异常,同时补充了线程安全的访问支持。 -
实体组配置调整 修改了
Launcher.unity场景中的UGF EntityGroup配置:将Enemy实体组的实例上限从原来的500调整为10000,另一项原值为60的配置同步做了调整(暂未关联特定需求,后续确认后补充说明)。 调整Enemy组上限的原因是UGF的EntityGroup对应的对象池是同组混存的:不同模型、不同逻辑的敌人都会归在Enemy这个组的对象池中,原来的500上限冗余不足,容易出现某类敌人需要批量生成时对象池空间不足的问题,拉到10000是为了留足缓冲空间。 -
冗余文件清理 开发过程中临时创建ObjectBase文件夹时误提交了对应的
.meta文件,确认该文件夹无用后已经删除对应的冗余meta文件。
设计思路与权衡
这次给EnemyManager做全量的职责拆分,核心原因是原来的单类承载了太多功能:刷怪策略、生成调度、敌人生命周期管理全堆在一个类里,代码越堆越厚,改任何一小块逻辑都要翻几百行,还容易影响其他不相关的功能。拆成策略、注册、调度三个独立组件之后,每个类的职责单一、边界清晰,后续要做运行时动态调控出怪策略、敌人数量管控、异步刷怪这些规划中的需求时,只要在对应的组件里迭代就行,不用动EnemyManager的核心逻辑,不管是维护还是扩展都方便很多。
目前的并发修复方案是针对当前遇到的关卡切换时序问题做的,暂时没有引入太重的线程安全机制,如果后续要加更多多线程操作敌人集合的场景(比如后台异步预加载敌人、全局数据统计),可能还要评估换用线程安全集合或者加更细粒度的锁,目前先保证现有场景的性能和稳定性。
后续关注点
- 重构回归验证:确认职责拆分后,刷怪逻辑、敌人增删、关卡切换等核心流程没有引入回归bug,重点检查跨组件的调用有没有漏改的情况。
- 并发方案验证:测试极端场景下的关卡切换(比如大量敌人异步加载时触发切关卡),确认CancelToken的逻辑覆盖了所有异步流程,不会出现状态错乱的问题。后续如果新增多线程操作敌人集合的需求,再评估是否要优化线程安全机制。
- 架构合理性验证:后续做动态刷怪策略、敌人数量动态调控等需求时,验证本次拆分的接口和组件是否足够灵活,有没有设计冗余或者边界考虑不到位的地方。
- 对象池内存评估:Enemy实体组上限拉到10000后,跟踪高刷怪量场景下的内存占用,评估对象池会不会占用过多内存,必要时再调整上限或者优化对象回收策略。
注:本文由模型
doubao-pro生成(草稿与终稿同模型)。