Files
zeling_v2/Assets/Scripts/Core/Difficulty/DifficultyManager.cs
2026-05-12 15:34:08 +08:00

80 lines
2.9 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 UnityEngine;
using BaseGames.Core.Events;
using BaseGames.Core.Save;
namespace BaseGames.Core
{
/// <summary>
/// 难度管理器(单例 MonoBehaviour
/// 统一管理当前难度档位,并通过事件频道广播变化。
/// 订阅者通过 <see cref="CurrentScaler"/> 获取具体缩放数值。
/// </summary>
[DefaultExecutionOrder(-900)]
public class DifficultyManager : MonoBehaviour, ISaveable, IDifficultyService
{
[SerializeField] private DifficultyScalerSO[] _allScalers;
[SerializeField] private DifficultyChangedEventChannel _onDifficultyChanged;
public DifficultyLevel CurrentLevel { get; private set; } = DifficultyLevel.Normal;
public DifficultyScalerSO CurrentScaler { get; private set; }
private void Awake()
{
if (ServiceLocator.GetOrDefault<IDifficultyService>() != null) { Destroy(gameObject); return; }
ServiceLocator.Register<IDifficultyService>(this);
Apply(DifficultyLevel.Normal);
ServiceLocator.GetOrDefault<ISaveableRegistry>()?.Register(this);
}
private void OnDestroy()
{
ServiceLocator.Unregister<IDifficultyService>(this);
ServiceLocator.GetOrDefault<ISaveableRegistry>()?.Unregister(this);
}
/// <summary>
/// 在游戏流程中切换难度。
/// SteelSoul 模式一旦选定,中途无法降级。
/// </summary>
public void ChangeDifficulty(DifficultyLevel level)
{
if (CurrentLevel == DifficultyLevel.SteelSoul && level != DifficultyLevel.SteelSoul)
{
Debug.LogWarning("[DifficultyManager] SteelSoul 模式无法在游戏中途降级。");
return;
}
Apply(level);
}
/// <summary>按档位查找对应的缩放器,未配置时返回 null。</summary>
public DifficultyScalerSO GetScaler(DifficultyLevel level)
{
if (_allScalers == null) return null;
foreach (var s in _allScalers)
if (s != null && s.Level == level) return s;
return null;
}
private void Apply(DifficultyLevel level)
{
CurrentLevel = level;
CurrentScaler = GetScaler(level);
_onDifficultyChanged?.Raise(CurrentLevel);
}
// ── ISaveable ────────────────────────────────────────────────────────
public void OnSave(SaveData saveData)
{
if (saveData?.Meta != null)
saveData.Meta.IsSteelSoul = CurrentLevel == DifficultyLevel.SteelSoul;
}
public void OnLoad(SaveData saveData)
{
if (saveData?.Meta != null && saveData.Meta.IsSteelSoul)
Apply(DifficultyLevel.SteelSoul);
}
}
}