using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using Utils; // 假设此命名空间包含MonoSingleton namespace Base { public interface ITick { public void Tick(); } public interface ITickPhysics { public void TickPhysics(); } public interface ITickUI { public void TickUI(); } public class Clock : MonoSingleton { private bool _pause = false; public bool Pause { get => _pause; set { if (value != _pause) // 逻辑修改说明:避免重复设置Time.timeScale { Time.timeScale = value ? 0 : 1; _pause = value; } } } // 修改点 1.1:主列表用于迭代 private readonly List _ticks = new(); private readonly List _tickPhysics = new(); private readonly List _tickUIs = new(); // 修改点 1.1:缓冲列表用于添加 private readonly HashSet _ticksToAdd = new(); // 逻辑修改说明:使用HashSet避免重复添加,提高查找效率 private readonly HashSet _tickPhysicsToAdd = new(); private readonly HashSet _tickUIsToAdd = new(); // 修改点 1.1:缓冲列表用于移除 private readonly HashSet _ticksToRemove = new(); // 逻辑修改说明:使用HashSet避免重复移除,提高查找效率 private readonly HashSet _tickPhysicsToRemove = new(); private readonly HashSet _tickUIsToRemove = new(); private void Update() { // 逻辑修改说明:UI部分的Tick不应受_pause影响 if (!_pause) { // 逻辑修改说明:迭代时使用只读副本或确保不会被修改 // 这里是直接迭代_ticks,确保_ticks在Update生命周期内不会被Add/Remove直接修改 // 添加和移除操作通过缓冲区在LateUpdate处理 foreach (var tick in _ticks) { tick.Tick(); } } // UI更新通常不受游戏暂停影响(例如菜单动画、UI计时器等),除非UI本身也需要暂停逻辑。 // 根据需求决定是否受_pause影响。此处假设UI不暂停。 foreach (var uiTick in _tickUIs) { uiTick.TickUI(); } } private void FixedUpdate() { if (!_pause) { foreach (var physicsTick in _tickPhysics) { physicsTick.TickPhysics(); } } } // 修改点 1.4:在LateUpdate应用缓冲区的更改 private void LateUpdate() { ApplyBufferedChanges(); } // 修改点 3.1:OnDestroy保持不变,确保事件移除 private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } // 修改点 3.1:OnStart保持不变,负责事件注册和初始化 protected override void OnStart() // MonoSingleton的Awake后调用 { SceneManager.sceneLoaded += OnSceneLoaded; // 逻辑修改说明:Initial清理所有列表,而不是填充 Init(); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { Init(); } /// /// 初始化/重置方法。清空所有注册列表和缓冲列表。 /// // 修改点 2.1:Init() 方法不再负责FindObjectsByType public void Init() { _ticks.Clear(); _tickPhysics.Clear(); _tickUIs.Clear(); _ticksToAdd.Clear(); _tickPhysicsToAdd.Clear(); _tickUIsToAdd.Clear(); _ticksToRemove.Clear(); _tickPhysicsToRemove.Clear(); _tickUIsToRemove.Clear(); // 逻辑修改说明:移除 FindObjectsByType 逻辑 // 对象应通过其各自的 OnEnable/OnDisable 生命周期来注册/反注册 foreach (var obj in FindObjectsByType(FindObjectsSortMode.None)) { if (obj is ITick tickObj) _ticks.Add(tickObj); if (obj is ITickPhysics physicsObj) _tickPhysics.Add(physicsObj); if (obj is ITickUI uiObj) _tickUIs.Add(uiObj); } } // 修改点 1.2 & 1.3:将更改放入缓冲,并在LateUpdate统一处理 public static void AddTick(ITick tick) { if (Instance != null && tick != null) // 逻辑修改说明:添加null检查 { Instance._ticksToAdd.Add(tick); Instance._ticksToRemove.Remove(tick); // 逻辑修改说明:如果在待移除列表,则先移除 } } public static void RemoveTick(ITick tick) { if (Instance != null && tick != null) // 逻辑修改说明:添加null检查 { Instance._ticksToRemove.Add(tick); Instance._ticksToAdd.Remove(tick); // 逻辑修改说明:如果在待添加列表,则先移除 } } public static void AddTickPhysics(ITickPhysics physics) { if (Instance != null && physics != null) { Instance._tickPhysicsToAdd.Add(physics); Instance._tickPhysicsToRemove.Remove(physics); } } public static void RemoveTickPhysics(ITickPhysics physics) { if (Instance != null && physics != null) { Instance._tickPhysicsToRemove.Add(physics); Instance._tickPhysicsToAdd.Remove(physics); } } public static void AddTickUI(ITickUI ui) { if (Instance != null && ui != null) { Instance._tickUIsToAdd.Add(ui); Instance._tickUIsToRemove.Remove(ui); } } public static void RemoveTickUI(ITickUI ui) { if (Instance != null && ui != null) { Instance._tickUIsToRemove.Add(ui); Instance._tickUIsToAdd.Remove(ui); } } // 修改点 1.3:应用缓冲区的更改 private void ApplyBufferedChanges() { // 先处理移除 if (_ticksToRemove.Count > 0) { foreach (var tick in _ticksToRemove) { _ticks.Remove(tick); } _ticksToRemove.Clear(); } if (_tickPhysicsToRemove.Count > 0) { foreach (var physicsTick in _tickPhysicsToRemove) { _tickPhysics.Remove(physicsTick); } _tickPhysicsToRemove.Clear(); } if (_tickUIsToRemove.Count > 0) { foreach (var uiTick in _tickUIsToRemove) { _tickUIs.Remove(uiTick); } _tickUIsToRemove.Clear(); } // 后处理添加 if (_ticksToAdd.Count > 0) { foreach (var tick in _ticksToAdd) { if (!_ticks.Contains(tick)) // 逻辑修改说明:避免重复添加到主列表 { _ticks.Add(tick); } } _ticksToAdd.Clear(); } if (_tickPhysicsToAdd.Count > 0) { foreach (var physicsTick in _tickPhysicsToAdd) { if (!_tickPhysics.Contains(physicsTick)) { _tickPhysics.Add(physicsTick); } } _tickPhysicsToAdd.Clear(); } if (_tickUIsToAdd.Count > 0) { foreach (var uiTick in _tickUIsToAdd) { if (!_tickUIs.Contains(uiTick)) { _tickUIs.Add(uiTick); } } _tickUIsToAdd.Clear(); } } } }