Files
Gen_Hack-and-Slash-Roguelit…/Client/Assets/Scripts/Base/Clock.cs

264 lines
8.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<Clock>
{
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<ITick> _ticks = new();
private readonly List<ITickPhysics> _tickPhysics = new();
private readonly List<ITickUI> _tickUIs = new();
// 修改点 1.1:缓冲列表用于添加
private readonly HashSet<ITick> _ticksToAdd = new(); // 逻辑修改说明使用HashSet避免重复添加提高查找效率
private readonly HashSet<ITickPhysics> _tickPhysicsToAdd = new();
private readonly HashSet<ITickUI> _tickUIsToAdd = new();
// 修改点 1.1:缓冲列表用于移除
private readonly HashSet<ITick> _ticksToRemove = new(); // 逻辑修改说明使用HashSet避免重复移除提高查找效率
private readonly HashSet<ITickPhysics> _tickPhysicsToRemove = new();
private readonly HashSet<ITickUI> _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.1OnDestroy保持不变确保事件移除
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
// 修改点 3.1OnStart保持不变负责事件注册和初始化
protected override void OnStart() // MonoSingleton的Awake后调用
{
SceneManager.sceneLoaded += OnSceneLoaded;
// 逻辑修改说明Initial清理所有列表而不是填充
Init();
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
Init();
}
/// <summary>
/// 初始化/重置方法。清空所有注册列表和缓冲列表。
/// </summary>
// 修改点 2.1Init() 方法不再负责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<MonoBehaviour>(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();
}
}
}
}