feat: 优化存档管理,增强链状态获取逻辑,添加 ISaveable 接口支持

This commit is contained in:
2026-05-20 16:37:32 +08:00
parent acb36d750f
commit 04aec4cc8e
4 changed files with 51 additions and 35 deletions

View File

@@ -1,6 +1,4 @@
using BaseGames.Combat;
using BaseGames.Core;
using BaseGames.Core.Save;
using BaseGames.Feedback;
using UnityEngine;
@@ -8,10 +6,11 @@ namespace BaseGames.World
{
/// <summary>
/// 假墙(秘密通道)。外观与普通墙相同,可通过攻击/接近揭示并穿越。
/// 揭示后禁用碰撞体(不销毁),状态持久化到 WorldSaveData
/// 揭示后禁用碰撞体(不销毁),状态通过 WorldStateRegistry 持久化
/// WorldStateRegistrySaverISaveable统一负责将 Door 分类写入存档。
/// </summary>
[RequireComponent(typeof(Collider2D))]
public class FalseWall : MonoBehaviour, IDamageable, ISaveable
public class FalseWall : MonoBehaviour, IDamageable
{
public enum RevealCondition { Proximity, AttackOnce, AlwaysOpen }
@@ -27,6 +26,10 @@ namespace BaseGames.World
[SerializeField] private SpriteRenderer _renderer;
[SerializeField] private SceneFeedback _revealFeedback;
[Header("World State")]
[Tooltip("绑定场景唯一的 WorldStateRegistry ScriptableObject用于持久化揭示状态。")]
[SerializeField] private WorldStateRegistry _registry;
private bool _isRevealed;
// ── IDamageable ───────────────────────────────────────────────────────
@@ -42,16 +45,6 @@ namespace BaseGames.World
// ── Unity Lifecycle ───────────────────────────────────────────────────
private void Awake()
{
ServiceLocator.GetOrDefault<ISaveableRegistry>()?.Register(this);
}
private void OnDestroy()
{
ServiceLocator.GetOrDefault<ISaveableRegistry>()?.Unregister(this);
}
private void Start()
{
if (_revealCondition == RevealCondition.AlwaysOpen)
@@ -60,21 +53,13 @@ namespace BaseGames.World
_isRevealed = true;
return;
}
}
// ── ISaveable ─────────────────────────────────────────────────────────
public void OnSave(SaveData data)
{
if (_isRevealed && !string.IsNullOrEmpty(_wallId)
&& !data.World.OpenedDoors.Contains(_wallId))
data.World.OpenedDoors.Add(_wallId);
}
public void OnLoad(SaveData data)
{
if (string.IsNullOrEmpty(_wallId)) return;
_isRevealed = data.World.OpenedDoors.Contains(_wallId);
if (_isRevealed) SetPassThroughImmediate();
// 从 WorldStateRegistry 恢复揭示状态(注册表由 WorldStateRegistrySaver.OnLoad 填充)
if (!string.IsNullOrEmpty(_wallId) && (_registry?.IsDoorOpened(_wallId) ?? false))
{
_isRevealed = true;
SetPassThroughImmediate();
}
}
private void OnTriggerEnter2D(Collider2D other)
@@ -90,6 +75,7 @@ namespace BaseGames.World
private void Reveal()
{
_isRevealed = true;
_registry?.MarkDoorOpened(_wallId);
_revealFeedback?.Play();
SetPassThroughImmediate();
}
@@ -118,3 +104,4 @@ namespace BaseGames.World
#endif
}
}