56 lines
2.5 KiB
C#
56 lines
2.5 KiB
C#
using UnityEngine;
|
||
using BaseGames.World;
|
||
|
||
namespace BaseGames.Dialogue
|
||
{
|
||
/// <summary>
|
||
/// 可交互 NPC 基类(架构 14_NarrativeModule §5)。
|
||
/// 实现 IInteractable,触发对话序列;子类(如 QuestGiver)可覆盖对话选择逻辑。
|
||
/// 程序集: BaseGames.Dialogue
|
||
/// </summary>
|
||
public class InteractableNPC : MonoBehaviour, IInteractable
|
||
{
|
||
[SerializeField] protected string _npcId;
|
||
[SerializeField] protected DialogueSequenceSO _defaultDialogue;
|
||
[SerializeField] protected float _interactRadius = 1.5f;
|
||
|
||
// ── IInteractable ──────────────────────────────────────────────────
|
||
public virtual bool CanInteract => true;
|
||
public virtual string InteractPrompt => "对话";
|
||
|
||
public void Interact(Transform player)
|
||
{
|
||
if (!CanInteract) return;
|
||
Interact_Internal(player);
|
||
var dialogue = GetCurrentDialogue();
|
||
if (dialogue != null)
|
||
PlayDialogue(dialogue, player);
|
||
}
|
||
|
||
public virtual void OnPlayerEnterRange(Transform player) { }
|
||
public virtual void OnPlayerExitRange() { }
|
||
|
||
// ── 子类覆盖点 ──────────────────────────────────────────────────────
|
||
|
||
/// <summary>交互前置逻辑(如任务接收/完成判断)。子类覆盖此方法。</summary>
|
||
protected virtual void Interact_Internal(Transform player) { }
|
||
|
||
/// <summary>返回当前应播放的对话序列。子类根据任务状态返回不同版本。</summary>
|
||
protected virtual DialogueSequenceSO GetCurrentDialogue() => _defaultDialogue;
|
||
|
||
// ── 对话播放 ───────────────────────────────────────────────────────
|
||
|
||
protected virtual void PlayDialogue(DialogueSequenceSO sequence, Transform player)
|
||
{
|
||
if (sequence == null) return;
|
||
var manager = BaseGames.Core.ServiceLocator.GetOrDefault<IDialogueService>();
|
||
if (manager == null)
|
||
{
|
||
Debug.LogWarning($"[InteractableNPC:{_npcId}] DialogueManager 未注册到 ServiceLocator,无法播放对话。");
|
||
return;
|
||
}
|
||
manager.StartDialogue(sequence, _npcId);
|
||
}
|
||
}
|
||
}
|