Files
gold_dolphin/unity/Assets/Architecture/Variables/VariableRegistry.cs
T
2026-07-07 03:34:56 +08:00

51 lines
2.3 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;
namespace Architecture
{
/// <summary>
/// 共享变量统一接口:所有 Variable 资产实现它,注册表才能统一重置。
/// </summary>
public interface IVariable
{
void ResetToDefault();
}
/// <summary>
/// 共享变量注册表 —— 运行时状态防泄漏的核心。
///
/// <b>问题</b>ScriptableObject 资产在 Editor 下跨 Play Mode 域重载会持久化其序列化值。
/// 例如 PlayerHealth.Value 在游玩中变为 0 后退出 Play Mode,若残留为 0,
/// 下次进入 Play Mode 可能直接触发死亡(或分数残留、开关状态错乱)。
///
/// <b>解决</b>:每个 Variable 在 OnEnable 时自动注册;每次进入 Play Mode(域加载前)
/// 由 [RuntimeInitializeOnLoadMethod] 统一调用 ResetToDefault()
/// 将运行时值恢复到设计器设置的 _defaultValue,杜绝跨局状态泄漏。
///
/// 注意:RuntimeInitializeLoadType.BeforeSceneLoad 在整个 Play Mode 生命周期内只触发一次,
/// 因此同一局内跨场景加载(SceneManager.LoadScene)不会重置变量,分数等跨场景共享状态可正常保留。
/// </summary>
public static class VariableRegistry
{
private static readonly HashSet<IVariable> _variables = new HashSet<IVariable>();
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();
}
}
}