using System.Collections.Generic;
using UnityEngine;
namespace Architecture
{
///
/// 共享变量统一接口:所有 Variable 资产实现它,注册表才能统一重置。
///
public interface IVariable
{
void ResetToDefault();
}
///
/// 共享变量注册表 —— 运行时状态防泄漏的核心。
///
/// 问题:ScriptableObject 资产在 Editor 下跨 Play Mode 域重载会持久化其序列化值。
/// 例如 PlayerHealth.Value 在游玩中变为 0 后退出 Play Mode,若残留为 0,
/// 下次进入 Play Mode 可能直接触发死亡(或分数残留、开关状态错乱)。
///
/// 解决:每个 Variable 在 OnEnable 时自动注册;每次进入 Play Mode(域加载前)
/// 由 [RuntimeInitializeOnLoadMethod] 统一调用 ResetToDefault(),
/// 将运行时值恢复到设计器设置的 _defaultValue,杜绝跨局状态泄漏。
///
/// 注意:RuntimeInitializeLoadType.BeforeSceneLoad 在整个 Play Mode 生命周期内只触发一次,
/// 因此同一局内跨场景加载(SceneManager.LoadScene)不会重置变量,分数等跨场景共享状态可正常保留。
///
public static class VariableRegistry
{
private static readonly HashSet _variables = new HashSet();
public static void Register(IVariable variable)
{
_variables.Add(variable);
// 注册即重置:解决 [RuntimeInitializeOnLoadMethod(BeforeSceneLoad)] 在 SO 资产
// 尚未 OnEnable 注册前就执行 ResetAll(此时 _variables 为空)导致重置无效的问题。
// 无论 ResetAll 何时触发,变量在「上线」瞬间都会被恢复到 _defaultValue,
// 杜绝退出 Play Mode 后 PlayerHealth 残留 0、再次进入直接触发死亡的跨局泄漏。
variable.ResetToDefault();
}
public static void Unregister(IVariable variable) => _variables.Remove(variable);
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void ResetAll()
{
foreach (var v in _variables)
v.ResetToDefault();
}
}
}