using BaseGames.Combat; using MoreMountains.Feedbacks; using UnityEngine; namespace BaseGames.World { /// /// 假墙(秘密通道)。外观与普通墙相同,可通过攻击/接近揭示并穿越。 /// 揭示后禁用碰撞体(不销毁),状态持久化到 WorldSaveData。 /// [RequireComponent(typeof(Collider2D))] public class FalseWall : MonoBehaviour, IDamageable { public enum RevealCondition { Proximity, AttackOnce, AlwaysOpen } [Header("识别")] [SerializeField] private string _wallId; [Header("揭示条件")] [SerializeField] private RevealCondition _revealCondition = RevealCondition.AttackOnce; [SerializeField] private float _proximityRadius = 2.0f; [Header("组件引用")] [SerializeField] private Collider2D _wallCollider; [SerializeField] private SpriteRenderer _renderer; [SerializeField] private MMF_Player _revealFeedback; private bool _isRevealed; // ── IDamageable ─────────────────────────────────────────────────────── public bool IsInvincible => _isRevealed; public int Defense => 0; public void TakeDamage(DamageInfo info) { if (_isRevealed || _revealCondition != RevealCondition.AttackOnce) return; Reveal(); } // ── Unity Lifecycle ─────────────────────────────────────────────────── private void Start() { if (_revealCondition == RevealCondition.AlwaysOpen) { SetPassThroughImmediate(); return; } // 读档恢复(SaveManager 集成后接入 WorldSaveData.RevealedFalseWalls) // 示例:bool revealed = ServiceLocator.GetOrDefault()?.CurrentSave?.World?.RevealedFalseWalls?.Contains(_wallId) ?? false; // if (revealed) SetPassThroughImmediate(); } private void OnTriggerEnter2D(Collider2D other) { if (_isRevealed || _revealCondition != RevealCondition.Proximity) return; if (!other.CompareTag("Player")) return; // Proximity 模式:仅播放 Shimmer 暗示,碰撞仍启用 _revealFeedback?.PlayFeedbacks(); } // ── Implementation ──────────────────────────────────────────────────── private void Reveal() { _isRevealed = true; _revealFeedback?.PlayFeedbacks(); SetPassThroughImmediate(); } private void SetPassThroughImmediate() { if (_wallCollider != null) _wallCollider.enabled = false; // 切换 Sprite 到透明/揭示帧(由子类或动画处理) } #if UNITY_EDITOR private void OnDrawGizmosSelected() { Gizmos.color = new Color(0.6f, 0.2f, 1f, 0.8f); var col = GetComponent(); if (col != null) Gizmos.DrawWireCube(transform.position, col.bounds.size); if (_revealCondition == RevealCondition.Proximity) { Gizmos.color = new Color(0.6f, 0.2f, 1f, 0.2f); Gizmos.DrawWireSphere(transform.position, _proximityRadius); } } #endif } }