using UnityEngine; using BaseGames.Core; using BaseGames.Core.Events; namespace BaseGames.Progression { /// /// 进程锁(架构 09_ProgressionModule §12)。 /// 单向/永久性阻挡,需满足特定条件(击败 Boss)才能解锁。 /// 通过 ServiceLocator.GetOrDefault<SaveManager>() 读取进度,订阅 BossDefeated 事件实时响应。 /// public class ProgressLock : MonoBehaviour { [Header("解锁条件")] [SerializeField] private string _requiredBossId; // 空 = 不检查 Boss [SerializeField] private string _requiredItemId; // 空 = 不检查道具(P1 预留) [Header("物理表现")] [SerializeField] private GameObject _lockedVisuals; // 锁住状态视觉 [SerializeField] private GameObject _unlockedVisuals; // 开启状态视觉(可 null) [SerializeField] private Collider2D _blockCollider; [Header("存档")] [SerializeField] private string _lockId; // 唯一 ID,存档记录开启状态 [Header("Event Channels")] [SerializeField] private StringEventChannelSO _onBossDefeated; // EVT_BossDefeated private readonly CompositeDisposable _subs = new(); private void Start() { ApplyState(CheckUnlocked()); } private void OnEnable() { _onBossDefeated?.Subscribe(OnBossDefeated).AddTo(_subs); } private void OnDisable() { _subs.Clear(); } private void OnBossDefeated(string bossId) { if (!string.IsNullOrEmpty(_requiredBossId) && bossId != _requiredBossId) return; if (CheckUnlocked()) ApplyState(true); } private bool CheckUnlocked() { var sm = ServiceLocator.GetOrDefault(); if (sm == null) return false; if (!string.IsNullOrEmpty(_requiredBossId) && !sm.IsBossDefeated(_requiredBossId)) return false; return string.IsNullOrEmpty(_lockId) || sm.IsDoorOpened(_lockId); } private void ApplyState(bool unlocked) { if (_blockCollider != null) _blockCollider.enabled = !unlocked; if (_lockedVisuals != null) _lockedVisuals.SetActive(!unlocked); if (_unlockedVisuals != null) _unlockedVisuals.SetActive(unlocked); } } }