From 76ed9a3e53bf5a531a7e3706bc5f2d107b8dbaa1 Mon Sep 17 00:00:00 2001 From: SepComet <202308010230@stu.csust.edu.cn> Date: Sun, 22 Feb 2026 10:12:26 +0800 Subject: [PATCH] =?UTF-8?q?Checkpoint=201=EF=BC=9A=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E9=94=81=E5=AE=9A=E4=B8=8E=E8=BF=90=E8=A1=8C=E5=BC=80=E5=85=B3?= =?UTF-8?q?=E8=90=BD=E5=9C=B0=20-=20=E5=9C=A8=20`SimulationWorld`=20?= =?UTF-8?q?=E9=87=8C=E6=B7=BB=E5=8A=A0=20P2=20=E8=BF=90=E8=A1=8C=E5=BC=80?= =?UTF-8?q?=E5=85=B3=20`UseJobSimulation`=20=E4=B8=8E=20`UseBurstJobs`=20-?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=E4=BE=9D=E8=B5=96=E5=8C=85=EF=BC=9A=20=09?= =?UTF-8?q?1.=20burst:=201.8.28=20=092.=20collections:=202.5.7=20=093.=20M?= =?UTF-8?q?athematics:=201.3.2=20=094.=20jobs=EF=BC=88=E4=B8=8D=E5=8D=95?= =?UTF-8?q?=E7=8B=AC=E6=88=90=E5=8C=85=EF=BC=89=20-=20=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=8C=E5=9D=87=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Scripts/Simulation/SimulationWorld.cs | 25 ++++++ Packages/manifest.json | 5 +- Packages/packages-lock.json | 48 ++++++++--- docs/TodoList.md | 79 +++++++++++++++---- .../references/SimulationDevelopmentSkill.md | 18 +++-- 5 files changed, 143 insertions(+), 32 deletions(-) diff --git a/Assets/GameMain/Scripts/Simulation/SimulationWorld.cs b/Assets/GameMain/Scripts/Simulation/SimulationWorld.cs index c263698..70f5954 100644 --- a/Assets/GameMain/Scripts/Simulation/SimulationWorld.cs +++ b/Assets/GameMain/Scripts/Simulation/SimulationWorld.cs @@ -35,6 +35,8 @@ namespace Simulation } [SerializeField] private bool _useSimulationMovement; + [SerializeField] private bool _useJobSimulation; + [SerializeField] private bool _useBurstJobs = true; private EntitySync _entitySync; private Presentation _presentation; @@ -53,12 +55,24 @@ namespace Simulation public IReadOnlyList Projectiles => _projectiles; public IReadOnlyList Pickups => _pickups; public bool UseSimulationMovement => _useSimulationMovement; + public bool UseJobSimulation => _useJobSimulation; + public bool UseBurstJobs => _useBurstJobs; public void SetUseSimulationMovement(bool enabled) { _useSimulationMovement = enabled; } + public void SetUseJobSimulation(bool enabled) + { + _useJobSimulation = enabled; + } + + public void SetUseBurstJobs(bool enabled) + { + _useBurstJobs = enabled; + } + protected override void Awake() { base.Awake(); @@ -266,6 +280,17 @@ namespace Simulation return; } + if (_useJobSimulation) + { + // Checkpoint 1: the switch is in place; Checkpoint 3+ will replace this with jobified path. + using (CustomProfilerMarker.TickEnemies.Auto()) + { + TickEnemies(in context); + } + + return; + } + using (CustomProfilerMarker.TickEnemies.Auto()) { TickEnemies(in context); diff --git a/Packages/manifest.json b/Packages/manifest.json index d54123a..b6ab6e0 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -1,14 +1,17 @@ { "dependencies": { + "com.unity.burst": "1.8.28", "com.unity.collab-proxy": "2.11.2", + "com.unity.collections": "2.5.7", "com.unity.ide.rider": "3.0.39", "com.unity.ide.visualstudio": "2.0.22", "com.unity.ide.vscode": "1.2.5", "com.unity.inputsystem": "1.14.2", + "com.unity.mathematics": "1.3.2", "com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.render-pipelines.universal": "14.0.12", "com.unity.test-framework": "1.1.33", - "com.unity.textmeshpro": "3.0.7", + "com.unity.textmeshpro": "3.0.9", "com.unity.timeline": "1.7.7", "com.unity.ugui": "1.0.0", "com.unity.visualscripting": "1.9.4", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 9f838b9..49c5036 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -1,8 +1,8 @@ { "dependencies": { "com.unity.burst": { - "version": "1.8.21", - "depth": 1, + "version": "1.8.28", + "depth": 0, "source": "registry", "dependencies": { "com.unity.mathematics": "1.2.1", @@ -17,9 +17,22 @@ "dependencies": {}, "url": "https://packages.unity.cn" }, + "com.unity.collections": { + "version": "2.5.7", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.burst": "1.8.19", + "com.unity.mathematics": "1.3.2", + "com.unity.test-framework": "1.4.6", + "com.unity.nuget.mono-cecil": "1.11.5", + "com.unity.test-framework.performance": "3.0.3" + }, + "url": "https://packages.unity.cn" + }, "com.unity.ext.nunit": { - "version": "1.0.6", - "depth": 1, + "version": "2.0.3", + "depth": 2, "source": "registry", "dependencies": {}, "url": "https://packages.unity.cn" @@ -59,7 +72,14 @@ "url": "https://packages.unity.cn" }, "com.unity.mathematics": { - "version": "1.2.6", + "version": "1.3.2", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.cn" + }, + "com.unity.nuget.mono-cecil": { + "version": "1.11.5", "depth": 1, "source": "registry", "dependencies": {}, @@ -120,18 +140,28 @@ } }, "com.unity.test-framework": { - "version": "1.1.33", - "depth": 0, + "version": "1.4.6", + "depth": 1, "source": "registry", "dependencies": { - "com.unity.ext.nunit": "1.0.6", + "com.unity.ext.nunit": "2.0.3", "com.unity.modules.imgui": "1.0.0", "com.unity.modules.jsonserialize": "1.0.0" }, "url": "https://packages.unity.cn" }, + "com.unity.test-framework.performance": { + "version": "3.0.3", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.1.31", + "com.unity.modules.jsonserialize": "1.0.0" + }, + "url": "https://packages.unity.cn" + }, "com.unity.textmeshpro": { - "version": "3.0.7", + "version": "3.0.9", "depth": 0, "source": "registry", "dependencies": { diff --git a/docs/TodoList.md b/docs/TodoList.md index cf39345..07e12e9 100644 --- a/docs/TodoList.md +++ b/docs/TodoList.md @@ -111,20 +111,68 @@ - Simulation 层与表现层边界清晰,可无缝衔接 P2 Job/Burst 改造。 ## 3. P2 Job System + Burst 落地(核心性能阶段) -- [ ] 引入并锁定依赖版本(Unity 2022.3 对应): - - `com.unity.collections` - - `com.unity.jobs` - - `com.unity.burst` - - `com.unity.mathematics` -- [ ] 第一批 Job 化模块(优先级从高到低): - 1. 敌人移动与朝向更新(`IJobParallelFor`)。 - 2. 目标选择加速(空间哈希/网格分桶,减少全量最近邻搜索)。 - 3. 投射物批量移动与寿命回收。 - 4. AOE/碰撞候选筛选(先 broad phase,后精算)。 -- [ ] Burst 编译策略: - - 热路径 Job 全部 `[BurstCompile]`。 - - 禁止在 Job 内使用托管分配、虚调用、LINQ。 -- [ ] 主线程仅做:输入采样、状态切换、UI同步、实体显隐。 +- [x] Checkpoint 1:依赖锁定与运行开关落地 + - 在 `Packages/manifest.json` 锁定并确认版本: + - `com.unity.collections` + - `com.unity.jobs`(已废弃并并入 `com.unity.collections`,Unity 2022.3 不再单独锁定包) + - `com.unity.burst` + - `com.unity.mathematics` + - 增加 P2 运行开关(建议): + - `UseJobSimulation` + - `UseBurstJobs` + - 约束:默认可一键回退到 P1.5 路径,避免全量切换导致定位困难。 + - 完成标准:Editor/Development Build 均可编译运行;关闭开关时行为与 P1.5 一致。 + +- [ ] Checkpoint 2:Simulation 与 Job 数据通道打通(仅建通道,不改行为) + - 为敌人/投射物建立 Job 输入输出结构(纯数据,不含 `Transform`/托管引用)。 + - 建立 `SimulationWorld -> NativeContainer -> SimulationWorld` 的拷贝与回写流程。 + - 统一生命周期:`Allocator.Persistent` 分配、集中 `Dispose`,避免泄漏。 + - 完成标准:战斗循环可稳定运行,且该通道持续帧无新增 GC Alloc 热点。 + +- [ ] Checkpoint 3:敌人移动与朝向 Job 化(第一优先) + - 将敌人移动、朝向更新迁移至 `IJobParallelFor`。 + - 输入最少包含:`position/forward/speed/targetPosition/deltaTime/state`。 + - 输出最少包含:`nextPosition/nextForward/isMoving`。 + - 保留 A/B 路径:可切换 Job 与旧逻辑对比。 + - 完成标准:开启 Job 后敌人追踪行为视觉一致;`TickEnemies` 主线程耗时明显下降。 + +- [ ] Checkpoint 4:目标选择加速(空间哈希/网格分桶) + - 建立敌人/目标的空间索引容器(建议 `NativeParallelMultiHashMap` 或等价结构)。 + - 拆分为两个阶段: + - 构建分桶(Build Buckets) + - 邻域候选查询(Query Neighbors) + - 避免全量最近邻搜索,控制复杂度随敌人数增长的斜率。 + - 完成标准:`3k` 敌人下目标选择阶段耗时稳定,且无索引越界/漏目标回归。 + +- [ ] Checkpoint 5:投射物批量移动与寿命回收 Job 化 + - 投射物数据结构最少包含:`position/velocity/lifeTime/age/active`。 + - 迁移投射物移动、越界判定、寿命回收到 Job。 + - 回收后保持实体池与索引同步,防止悬空引用。 + - 完成标准:连续战斗下投射物数量曲线稳定,无异常积压或提前回收。 + +- [ ] Checkpoint 6:AOE/碰撞候选筛选 Job 化(Broad Phase 优先) + - 先 Job 化候选生成(Broad Phase),减少精算对数。 + - 精算与伤害结算可先保留主线程,但输入改为候选列表驱动。 + - 建立命中事件缓冲区,统一在主线程提交表现层事件。 + - 完成标准:命中结果与现有逻辑一致,候选数量与耗时显著下降。 + +- [ ] Checkpoint 7:Burst 策略落地与热路径约束 + - 热路径 Job 全部添加 `[BurstCompile]`,并在 Burst Inspector 确认已生效。 + - 清理 Job 内不兼容写法:托管分配、虚调用、LINQ、异常路径热调用。 + - 数学计算统一迁移到 `Unity.Mathematics`。 + - 完成标准:核心 Job 均由 Burst 编译,且无安全检查错误/降级回 Mono 的关键路径。 + +- [ ] Checkpoint 8:主线程职责收口与调度稳定 + - 明确主线程只做:输入采样、状态切换、UI 同步、实体显隐、最终写回。 + - 统一 `Schedule -> Dependency Combine -> Complete` 位置,防止隐式同步抖动。 + - 清理战斗帧中不必要的主线程循环(尤其逐实体逻辑)。 + - 完成标准:Profiler 可见主要计算在 Worker Threads;Main Thread 峰值更平滑。 + +- [ ] Checkpoint 9:P2 回归、压测与结项文档 + - 回归用例:10 分钟战斗、`Battle -> LevelUp -> Shop -> Battle` 循环、掉落拾取链路。 + - 压测口径:`1k/2k/3k` 敌人,记录 Main Thread、Job Workers、GC Alloc、关键 Marker。 + - 输出文档:`P2 Job/Burst 改造说明 + 开关/回滚策略 + 前后对比数据`。 + - 完成标准:结论可复现,可作为 P3 GPU Instancing 的输入基线。 **验收标准** - 在 3k 敌人规模下,CPU Main Thread 明显下降(目标 >= 30%)。 @@ -191,3 +239,6 @@ - [ ] Profiling 对比(改造前后同场景同参数)。 - [ ] 风险与回滚说明(特别是热更新与渲染链路)。 +## 测试命令 +- PlayMode: `Unity -batchmode -nographics -projectPath . -runTests -testPlatform PlayMode -testResults Logs/playmode-test-results.xml -logFile Logs/playmode-tests.log` +- EditMode: `Unity -batchmode -nographics -projectPath . -runTests -testPlatform EditMode -testResults Logs/editmode-test-results.xml -logFile Logs/editmode-tests.log` \ No newline at end of file diff --git a/skills/simulation-development/references/SimulationDevelopmentSkill.md b/skills/simulation-development/references/SimulationDevelopmentSkill.md index 87fb71c..c45f4fe 100644 --- a/skills/simulation-development/references/SimulationDevelopmentSkill.md +++ b/skills/simulation-development/references/SimulationDevelopmentSkill.md @@ -32,13 +32,13 @@ ## 生命周期与数据同步设计 `EntitySync` 通过事件驱动保持 Simulation 容器与实体生命周期一致: -| 事件 | 组名 | 行为 | -|---|---|---| -| `ShowEntitySuccessEventArgs` | `Enemy` | `RegisterEnemyLifecycle` + `UpsertEnemy` | -| `HideEntityCompleteEventArgs` | `Enemy` | `UnregisterEnemyLifecycle` + `RemoveEnemyByEntityId` | -| `ShowEntitySuccessEventArgs` | `Drop` | `RegisterPickupLifecycle` + `UpsertPickup` | -| `HideEntityCompleteEventArgs` | `Drop` | `UnregisterPickupLifecycle` + `RemovePickupByEntityId` | -| `ShowEntitySuccessEventArgs` | `Bullet` / `Projectile` | `RegisterProjectileLifecycle` + `UpsertProjectile` | +| 事件 | 组名 | 行为 | +|-------------------------------|-------------------------|----------------------------------------------------------------| +| `ShowEntitySuccessEventArgs` | `Enemy` | `RegisterEnemyLifecycle` + `UpsertEnemy` | +| `HideEntityCompleteEventArgs` | `Enemy` | `UnregisterEnemyLifecycle` + `RemoveEnemyByEntityId` | +| `ShowEntitySuccessEventArgs` | `Drop` | `RegisterPickupLifecycle` + `UpsertPickup` | +| `HideEntityCompleteEventArgs` | `Drop` | `UnregisterPickupLifecycle` + `RemovePickupByEntityId` | +| `ShowEntitySuccessEventArgs` | `Bullet` / `Projectile` | `RegisterProjectileLifecycle` + `UpsertProjectile` | | `HideEntityCompleteEventArgs` | `Bullet` / `Projectile` | `UnregisterProjectileLifecycle` + `RemoveProjectileByEntityId` | 关键规则: @@ -117,7 +117,9 @@ - Android 端评估以 CPU `ms` 为主,`fps` 受 60 上限影响 ## 自动化回归(P1.5 已补) -目录:`Assets/Tests/Simulation/EditMode/SimulationWorldTickTests.cs` +目录: + - `Assets/Tests/Simulation/EditMode/SimulationWorldTickTests.cs` + - `Assets/Tests/Simulation/PlayMode/SimulationWorldPlayModeTests.cs` 覆盖点: - 敌人追踪玩家