From f37658a48184414c497a5209d07686dfedb6e151 Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Mon, 1 Dec 2025 17:54:03 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=B6=E6=AE=B52/IUpdateable=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...1_1_performance_optimization_aggressive.md | 67 +++++++++++++++++-- Assets/Scripts/Framework/ScriptableObject.cs | 66 +++++++++++++++++- .../Framework/UpdateScheduler/IUpdateable.cs | 4 +- .../UpdateScheduler/UpdateScheduler.cs | 4 +- 4 files changed, 131 insertions(+), 10 deletions(-) diff --git a/.tasks/2025-12-01_1_performance_optimization_aggressive.md b/.tasks/2025-12-01_1_performance_optimization_aggressive.md index c1880a9..3cdea91 100644 --- a/.tasks/2025-12-01_1_performance_optimization_aggressive.md +++ b/.tasks/2025-12-01_1_performance_optimization_aggressive.md @@ -293,7 +293,7 @@ using (Profiler.BeginZone("BurstJob.Schedule")) 每个Phase完成后打tag,必要时可回滚 # 当前执行步骤: -"阶段1.6 - 阶段1整体测试" +"阶段2.5 - 阶段2整体测试" # 任务进度 @@ -345,12 +345,69 @@ using (Profiler.BeginZone("BurstJob.Schedule")) - 更改:基础设施搭建完成(3个新文件,RootObject修改2处) - 原因:验证阶段1无破坏性影响 - 测试项目: - 1. 编译项目 - 已通过(无linter错误) + 1. 编译项目 - ✅ 已通过(无linter错误) + 2. 运行编辑器 - ✅ 用户确认成功 + 3. 打开项目 - ✅ 用户确认成功 + 4. 检查RootObject.Scheduler字段 - ✅ 用户确认成功 + 5. 关闭项目 - ✅ 用户确认成功 + 6. 检查控制台无错误 - ✅ 用户确认成功 +- 阻碍因素:无 +- 状态:✅ 成功 +- Commit: 用户已提交 + +## 阶段2:接口适配 + +### 2.1 ScriptableObject添加IUpdateable接口声明 +[2025-12-01 17:30:00] +- 已修改:ScriptableObject.cs 类声明 (Line 582,添加IUpdateable接口) +- 更改:ScriptableObject实现IUpdateable接口 +- 原因:使所有ScriptableObject可以被调度器管理 +- 阻碍因素:无 +- 状态:未确认 + +### 2.2 添加Update模式字段 +[2025-12-01 17:32:15] +- 已修改:ScriptableObject.cs (添加3个字段,Line 111-116) +- 更改:添加_updateMode、_activeStartTime、_activeEndTime字段 +- 原因:存储对象的Update模式和时间范围 +- 阻碍因素:无 +- 状态:未确认 + +### 2.3 添加虚方法供子类重写 +[2025-12-01 17:34:30] +- 已修改:ScriptableObject.cs (添加2个虚方法,Line 175-183) +- 更改:添加GetUpdateMode和GetActiveTimeRange虚方法 +- 原因:允许子类自定义Update模式和时间范围 +- 阻碍因素:无 +- 状态:未确认 + +### 2.4 实现IUpdateable接口方法 +[2025-12-01 17:36:45] +- 已修改:ScriptableObject.cs (添加新的partial class,约35行,Line 916-950) +- 更改:实现IUpdateable的3个接口方法(ExecuteUpdate、GetUpdateName、IsUpdateReady) +- 原因:提供扁平化Update入口,复用原有UpdateTicks逻辑 +- 阻碍因素:无 +- 状态:未确认 + +### 2.4.1 重命名方法为FlatOptimizationUpdate(更具描述性) +[2025-12-01 17:40:00] +- 已修改:IUpdateable.cs、UpdateScheduler.cs、ScriptableObject.cs +- 更改:将方法重命名为FlatOptimizationUpdate,明确表达"扁平化优化Update"的含义 +- 原因:提高代码可读性,方法名清晰表达优化目的 +- 阻碍因素:无 +- 状态:未确认 + +### 2.5 阶段2整体测试 +[2025-12-01 17:38:00] +- 已修改:阶段2所有代码完成,等待测试 +- 更改:ScriptableObject完整实现IUpdateable接口(添加3个字段、2个虚方法、3个接口方法) +- 原因:验证接口实现无破坏性影响 +- 测试项目: + 1. 编译项目 - ✅ 已通过(无linter错误) 2. 运行编辑器 - 待测试 3. 打开项目 - 待测试 - 4. 检查RootObject.Scheduler字段 - 待测试 - 5. 关闭项目 - 待测试 - 6. 检查控制台无错误 - 待测试 + 4. 检查Inspector中新增字段是否可见 - 待测试 + 5. 验证游戏功能不受影响 - 待测试 - 阻碍因素:无 - 状态:未确认 → 等待用户确认:成功/不成功? diff --git a/Assets/Scripts/Framework/ScriptableObject.cs b/Assets/Scripts/Framework/ScriptableObject.cs index 8450dcf..31a31da 100644 --- a/Assets/Scripts/Framework/ScriptableObject.cs +++ b/Assets/Scripts/Framework/ScriptableObject.cs @@ -107,6 +107,15 @@ namespace Demo EnterGameLocalScaling = Vector3.one; [Content, SerializeField] private bool IsSetObjectDisable = false; [Content] public int UpdatePerFrame = 1; + + [Content, SerializeField, Header("UpdateMode")] + protected UpdateMode _updateMode = UpdateMode.Permanent; + + [Content, SerializeField] + protected float _activeStartTime = 0f; + + [Content, SerializeField] + protected float _activeEndTime = float.MaxValue; /// /// 设置坐标 @@ -162,6 +171,17 @@ namespace Demo { UpdatePerFrame = Mathf.Max(1, frame); } + + /// + /// 子类可重写,定义自己的Update模式 + /// + protected virtual UpdateMode GetUpdateMode() => UpdateMode.Permanent; + + /// + /// 子类可重写,定义自己的活跃时间范围 + /// + protected virtual (float start, float end) GetActiveTimeRange() + => (0f, float.MaxValue); private void ScriptableObjectDoReset() { @@ -579,7 +599,8 @@ namespace Demo #else MonoBehaviour, #endif - IHierarchyItemClickEventListener + IHierarchyItemClickEventListener, + IUpdateable { protected virtual IEnumerator DoSomethingDuringApplyScript() { @@ -891,4 +912,47 @@ namespace Demo return new(color.x, color.y, color.z); } } + + /// + /// IUpdateable接口实现 + /// + public partial class ScriptableObject + { + /// + /// IUpdateable.FlatOptimizationUpdate实现 - 扁平化优化Update入口,直接更新对象自身(无递归遍历子对象) + /// + public void FlatOptimizationUpdate(float currentTime, float deltaTime, TickType tickType) + { + if (IsScriptApply == false) + return; + if (gameObject.activeInHierarchy == false) + return; + + // 只更新自己,不递归子节点 + if (this.IsSelfEnableUpdate && UpdatePerFrame > 0) + { + if (ScriptUpdateCounter % UpdatePerFrame == 0) + { + using (Profiler.BeginZone($"{this.ScriptName}.UpdateTicks")) + { + UpdateTicks(currentTime, deltaTime, tickType); + } + } + ScriptUpdateCounter += tickType == TickType.Update ? 1 : 0; + } + } + + /// + /// IUpdateable.GetUpdateName实现 + /// + public string GetUpdateName() + { + return $"{ScriptName}<{GetType().Name}>"; + } + + /// + /// IUpdateable.IsUpdateReady实现 + /// + public bool IsUpdateReady => IsScriptApply; + } } diff --git a/Assets/Scripts/Framework/UpdateScheduler/IUpdateable.cs b/Assets/Scripts/Framework/UpdateScheduler/IUpdateable.cs index 323cb3f..8eba2d3 100644 --- a/Assets/Scripts/Framework/UpdateScheduler/IUpdateable.cs +++ b/Assets/Scripts/Framework/UpdateScheduler/IUpdateable.cs @@ -8,9 +8,9 @@ namespace Demo.Game public interface IUpdateable { /// - /// 直接Update调用,无递归 + /// 扁平化优化Update调用,直接更新对象自身(无递归遍历子对象) /// - void DoUpdate(float currentTime, float deltaTime, ScriptableObject.TickType tickType); + void FlatOptimizationUpdate(float currentTime, float deltaTime, ScriptableObject.TickType tickType); /// /// 对象名称,用于调试 diff --git a/Assets/Scripts/Framework/UpdateScheduler/UpdateScheduler.cs b/Assets/Scripts/Framework/UpdateScheduler/UpdateScheduler.cs index 4e12dfa..ab83583 100644 --- a/Assets/Scripts/Framework/UpdateScheduler/UpdateScheduler.cs +++ b/Assets/Scripts/Framework/UpdateScheduler/UpdateScheduler.cs @@ -113,7 +113,7 @@ namespace Demo.Game { if (permanentObjects[i]?.IsUpdateReady == true) { - permanentObjects[i].DoUpdate(currentTime, deltaTime, tickType); + permanentObjects[i].FlatOptimizationUpdate(currentTime, deltaTime, tickType); } } @@ -126,7 +126,7 @@ namespace Demo.Game continue; } - activeObjects[i].DoUpdate(currentTime, deltaTime, tickType); + activeObjects[i].FlatOptimizationUpdate(currentTime, deltaTime, tickType); } } }