Checkpoint 1:依赖锁定与运行开关落地

- 在 `SimulationWorld` 里添加 P2 运行开关 `UseJobSimulation` 与 `UseBurstJobs`
- 添加依赖包:
	1. burst: 1.8.28
	2. collections: 2.5.7
	3. Mathematics: 1.3.2
	4. jobs(不单独成包)
- 运行测试,均通过
This commit is contained in:
SepComet 2026-02-22 10:12:26 +08:00
parent 0ae25b960a
commit 76ed9a3e53
5 changed files with 143 additions and 32 deletions

View File

@ -35,6 +35,8 @@ namespace Simulation
} }
[SerializeField] private bool _useSimulationMovement; [SerializeField] private bool _useSimulationMovement;
[SerializeField] private bool _useJobSimulation;
[SerializeField] private bool _useBurstJobs = true;
private EntitySync _entitySync; private EntitySync _entitySync;
private Presentation _presentation; private Presentation _presentation;
@ -53,12 +55,24 @@ namespace Simulation
public IReadOnlyList<ProjectileSimData> Projectiles => _projectiles; public IReadOnlyList<ProjectileSimData> Projectiles => _projectiles;
public IReadOnlyList<PickupSimData> Pickups => _pickups; public IReadOnlyList<PickupSimData> Pickups => _pickups;
public bool UseSimulationMovement => _useSimulationMovement; public bool UseSimulationMovement => _useSimulationMovement;
public bool UseJobSimulation => _useJobSimulation;
public bool UseBurstJobs => _useBurstJobs;
public void SetUseSimulationMovement(bool enabled) public void SetUseSimulationMovement(bool enabled)
{ {
_useSimulationMovement = enabled; _useSimulationMovement = enabled;
} }
public void SetUseJobSimulation(bool enabled)
{
_useJobSimulation = enabled;
}
public void SetUseBurstJobs(bool enabled)
{
_useBurstJobs = enabled;
}
protected override void Awake() protected override void Awake()
{ {
base.Awake(); base.Awake();
@ -266,6 +280,17 @@ namespace Simulation
return; 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()) using (CustomProfilerMarker.TickEnemies.Auto())
{ {
TickEnemies(in context); TickEnemies(in context);

View File

@ -1,14 +1,17 @@
{ {
"dependencies": { "dependencies": {
"com.unity.burst": "1.8.28",
"com.unity.collab-proxy": "2.11.2", "com.unity.collab-proxy": "2.11.2",
"com.unity.collections": "2.5.7",
"com.unity.ide.rider": "3.0.39", "com.unity.ide.rider": "3.0.39",
"com.unity.ide.visualstudio": "2.0.22", "com.unity.ide.visualstudio": "2.0.22",
"com.unity.ide.vscode": "1.2.5", "com.unity.ide.vscode": "1.2.5",
"com.unity.inputsystem": "1.14.2", "com.unity.inputsystem": "1.14.2",
"com.unity.mathematics": "1.3.2",
"com.unity.nuget.newtonsoft-json": "3.2.2", "com.unity.nuget.newtonsoft-json": "3.2.2",
"com.unity.render-pipelines.universal": "14.0.12", "com.unity.render-pipelines.universal": "14.0.12",
"com.unity.test-framework": "1.1.33", "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.timeline": "1.7.7",
"com.unity.ugui": "1.0.0", "com.unity.ugui": "1.0.0",
"com.unity.visualscripting": "1.9.4", "com.unity.visualscripting": "1.9.4",

View File

@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"com.unity.burst": { "com.unity.burst": {
"version": "1.8.21", "version": "1.8.28",
"depth": 1, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {
"com.unity.mathematics": "1.2.1", "com.unity.mathematics": "1.2.1",
@ -17,9 +17,22 @@
"dependencies": {}, "dependencies": {},
"url": "https://packages.unity.cn" "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": { "com.unity.ext.nunit": {
"version": "1.0.6", "version": "2.0.3",
"depth": 1, "depth": 2,
"source": "registry", "source": "registry",
"dependencies": {}, "dependencies": {},
"url": "https://packages.unity.cn" "url": "https://packages.unity.cn"
@ -59,7 +72,14 @@
"url": "https://packages.unity.cn" "url": "https://packages.unity.cn"
}, },
"com.unity.mathematics": { "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, "depth": 1,
"source": "registry", "source": "registry",
"dependencies": {}, "dependencies": {},
@ -120,18 +140,28 @@
} }
}, },
"com.unity.test-framework": { "com.unity.test-framework": {
"version": "1.1.33", "version": "1.4.6",
"depth": 0, "depth": 1,
"source": "registry", "source": "registry",
"dependencies": { "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.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0" "com.unity.modules.jsonserialize": "1.0.0"
}, },
"url": "https://packages.unity.cn" "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": { "com.unity.textmeshpro": {
"version": "3.0.7", "version": "3.0.9",
"depth": 0, "depth": 0,
"source": "registry", "source": "registry",
"dependencies": { "dependencies": {

View File

@ -111,20 +111,68 @@
- Simulation 层与表现层边界清晰,可无缝衔接 P2 Job/Burst 改造。 - Simulation 层与表现层边界清晰,可无缝衔接 P2 Job/Burst 改造。
## 3. P2 Job System + Burst 落地(核心性能阶段) ## 3. P2 Job System + Burst 落地(核心性能阶段)
- [ ] 引入并锁定依赖版本Unity 2022.3 对应): - [x] Checkpoint 1依赖锁定与运行开关落地
- 在 `Packages/manifest.json` 锁定并确认版本:
- `com.unity.collections` - `com.unity.collections`
- `com.unity.jobs` - `com.unity.jobs`(已废弃并并入 `com.unity.collections`Unity 2022.3 不再单独锁定包)
- `com.unity.burst` - `com.unity.burst`
- `com.unity.mathematics` - `com.unity.mathematics`
- [ ] 第一批 Job 化模块(优先级从高到低): - 增加 P2 运行开关(建议):
1. 敌人移动与朝向更新(`IJobParallelFor`)。 - `UseJobSimulation`
2. 目标选择加速(空间哈希/网格分桶,减少全量最近邻搜索)。 - `UseBurstJobs`
3. 投射物批量移动与寿命回收。 - 约束:默认可一键回退到 P1.5 路径,避免全量切换导致定位困难。
4. AOE/碰撞候选筛选(先 broad phase后精算 - 完成标准Editor/Development Build 均可编译运行;关闭开关时行为与 P1.5 一致。
- [ ] Burst 编译策略:
- 热路径 Job 全部 `[BurstCompile]` - [ ] Checkpoint 2Simulation 与 Job 数据通道打通(仅建通道,不改行为)
- 禁止在 Job 内使用托管分配、虚调用、LINQ。 - 为敌人/投射物建立 Job 输入输出结构(纯数据,不含 `Transform`/托管引用)。
- [ ] 主线程仅做输入采样、状态切换、UI同步、实体显隐。 - 建立 `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 6AOE/碰撞候选筛选 Job 化Broad Phase 优先)
- 先 Job 化候选生成Broad Phase减少精算对数。
- 精算与伤害结算可先保留主线程,但输入改为候选列表驱动。
- 建立命中事件缓冲区,统一在主线程提交表现层事件。
- 完成标准:命中结果与现有逻辑一致,候选数量与耗时显著下降。
- [ ] Checkpoint 7Burst 策略落地与热路径约束
- 热路径 Job 全部添加 `[BurstCompile]`,并在 Burst Inspector 确认已生效。
- 清理 Job 内不兼容写法托管分配、虚调用、LINQ、异常路径热调用。
- 数学计算统一迁移到 `Unity.Mathematics`
- 完成标准:核心 Job 均由 Burst 编译,且无安全检查错误/降级回 Mono 的关键路径。
- [ ] Checkpoint 8主线程职责收口与调度稳定
- 明确主线程只做输入采样、状态切换、UI 同步、实体显隐、最终写回。
- 统一 `Schedule -> Dependency Combine -> Complete` 位置,防止隐式同步抖动。
- 清理战斗帧中不必要的主线程循环(尤其逐实体逻辑)。
- 完成标准Profiler 可见主要计算在 Worker ThreadsMain Thread 峰值更平滑。
- [ ] Checkpoint 9P2 回归、压测与结项文档
- 回归用例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%)。 - 在 3k 敌人规模下CPU Main Thread 明显下降(目标 >= 30%)。
@ -191,3 +239,6 @@
- [ ] Profiling 对比(改造前后同场景同参数)。 - [ ] 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`

View File

@ -33,7 +33,7 @@
`EntitySync` 通过事件驱动保持 Simulation 容器与实体生命周期一致: `EntitySync` 通过事件驱动保持 Simulation 容器与实体生命周期一致:
| 事件 | 组名 | 行为 | | 事件 | 组名 | 行为 |
|---|---|---| |-------------------------------|-------------------------|----------------------------------------------------------------|
| `ShowEntitySuccessEventArgs` | `Enemy` | `RegisterEnemyLifecycle` + `UpsertEnemy` | | `ShowEntitySuccessEventArgs` | `Enemy` | `RegisterEnemyLifecycle` + `UpsertEnemy` |
| `HideEntityCompleteEventArgs` | `Enemy` | `UnregisterEnemyLifecycle` + `RemoveEnemyByEntityId` | | `HideEntityCompleteEventArgs` | `Enemy` | `UnregisterEnemyLifecycle` + `RemoveEnemyByEntityId` |
| `ShowEntitySuccessEventArgs` | `Drop` | `RegisterPickupLifecycle` + `UpsertPickup` | | `ShowEntitySuccessEventArgs` | `Drop` | `RegisterPickupLifecycle` + `UpsertPickup` |
@ -117,7 +117,9 @@
- Android 端评估以 CPU `ms` 为主,`fps` 受 60 上限影响 - Android 端评估以 CPU `ms` 为主,`fps` 受 60 上限影响
## 自动化回归P1.5 已补) ## 自动化回归P1.5 已补)
目录:`Assets/Tests/Simulation/EditMode/SimulationWorldTickTests.cs` 目录:
- `Assets/Tests/Simulation/EditMode/SimulationWorldTickTests.cs`
- `Assets/Tests/Simulation/PlayMode/SimulationWorldPlayModeTests.cs`
覆盖点: 覆盖点:
- 敌人追踪玩家 - 敌人追踪玩家