63 lines
2.3 KiB
C#
63 lines
2.3 KiB
C#
using UnityEngine;
|
||
using BaseGames.World;
|
||
using BaseGames.Core.Events;
|
||
using BaseGames.Dialogue;
|
||
|
||
namespace BaseGames.World.Shop
|
||
{
|
||
/// <summary>
|
||
/// 商店 NPC 交互组件(架构 15_MapShopModule §2.4)。
|
||
/// 实现 IInteractable;玩家与其交互时先触发招呼对话,对话结束后打开商店面板。
|
||
/// 若无招呼对话,则直接打开商店。
|
||
/// </summary>
|
||
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();
|
||
}
|
||
}
|