using UnityEngine; using BaseGames.World; using BaseGames.Core.Events; using BaseGames.Dialogue; namespace BaseGames.World.Shop { /// /// 商店 NPC 交互组件(架构 15_MapShopModule §2.4)。 /// 实现 IInteractable;玩家与其交互时先触发招呼对话,对话结束后打开商店面板。 /// 若无招呼对话,则直接打开商店。 /// public class ShopNPC : MonoBehaviour, IInteractable { [Header("组件引用")] [SerializeField] private ShopController _shopController; [Header("招呼对话(可空,留空则直接开店)")] [SerializeField] private DialogueDataSO _greetDialogue; [Header("Event Channels")] [SerializeField] private DialogueEventChannelSO _dialogueChannel; // EVT_DialogueStart [SerializeField] private VoidEventChannelSO _onDialogueEnded; // EVT_DialogueEnded [Header("交互提示")] [SerializeField] private string _interactPrompt = "购买物品"; private EventSubscription _greetSub; // ── IInteractable ───────────────────────────────────────────────────── public bool CanInteract => _shopController != null; public string InteractPrompt => _interactPrompt; public void Interact(Transform player) { if (_greetDialogue != null && _dialogueChannel != null) { _greetSub.Dispose(); _greetSub = _onDialogueEnded.Subscribe(OnGreetDialogueEnded); _dialogueChannel.Raise(_greetDialogue); } else { OpenShop(); } } public void OnPlayerEnterRange(Transform player) { } public void OnPlayerExitRange() { } // ── 内部 ────────────────────────────────────────────────────────────── private void OnGreetDialogueEnded() { _greetSub.Dispose(); OpenShop(); } private void OpenShop() => _shopController?.Open(); } }