Files
Ipseity-Demo/Assets/Unheimlich_POC/Scripts/Handlers/Interactions/Dialogues/NPCDialogueTrigger.cs
T

142 lines
4.5 KiB
C#

using UnityEngine;
using Unheimlich.Interactions.Core;
using Unheimlich.Data.Dialogues;
using Unheimlich.Managers;
using Unheimlich.Gameplay.Player;
using Unheimlich.UI;
namespace Unheimlich.Interactions.Dialogues
{
/// <summary>
/// NPC interactable that starts dialogue conversations.
/// Rotates to face player during dialogue and pauses if player moves too far away.
/// </summary>
public class NPCDialogueTrigger : InteractableBase
{
[Header("Dialogue Reference")]
[Tooltip("DialogueConversation to use for this NPC")]
public DialogueConversation Conversation;
[Header("Trigger Settings")]
[Tooltip("Can the dialogue be retriggered after completion")]
[SerializeField] private bool _isRetriggerable = true;
[Header("Floating Word Setting")]
[SerializeField] private Transform _floatingWordAnchor;
[Header("Animation Settings")]
[SerializeField] private DialogueAnimationSettings _animationSettings;
[Header("UI Reference")]
[Tooltip("Local DialogueUI for this NPC. Uses DialogueManager's UI if null")]
[SerializeField] private DialogueUI _localDialogueUI;
[Header("Distance Settings")]
[Tooltip("Maximum distance before dialogue pauses")]
[SerializeField] private float _maxDialogueDistance = 5f;
[Header("Blur Effect")]
[Tooltip("Enable blur effect when dialogue starts")]
[SerializeField] private bool _enableBlurEffect = false;
public Transform FloatingWordAnchor => _floatingWordAnchor;
private bool _isDialogueActive = false;
private DialogueStateHandler _dialogueState;
private void Awake()
{
_dialogueState = new DialogueStateHandler(this);
}
private void Start()
{
InteractionText = "Talk";
}
private void Update()
{
if (_isDialogueActive && Player.Instance != null)
{
float distance = Vector3.Distance(transform.position, Player.Instance.transform.position);
if (distance > _maxDialogueDistance && DialogueManager.Instance != null && DialogueManager.Instance.IsDialogueActive)
{
if ((Object)DialogueManager.Instance.CurrentOwner == this)
{
_dialogueState.PauseDialogue();
_isDialogueActive = false;
}
}
else
LookAtPlayer();
}
}
public override void Interact(GameObject interactor)
{
if (DialogueManager.Instance == null)
return;
if (_dialogueState.IsCompleted && !_isRetriggerable)
return;
if (_dialogueState.HasPausedDialogue)
{
_dialogueState.ResumeDialogue();
DialogueManager.Instance.OnDialogueCompleted += OnDialogueCompleted;
_isDialogueActive = true;
if (_enableBlurEffect && DialogueBlurEffectURP.Instance != null)
DialogueBlurEffectURP.Instance.ShowBlur();
}
else
{
if (Conversation == null)
{
Debug.LogWarning($"NPC {gameObject.name} has no conversation configured!");
return;
}
DialogueManager.Instance.StartConversation(Conversation, _floatingWordAnchor, _animationSettings, _localDialogueUI, this);
DialogueManager.Instance.OnDialogueCompleted += OnDialogueCompleted;
_isDialogueActive = true;
if (_enableBlurEffect && DialogueBlurEffectURP.Instance != null)
DialogueBlurEffectURP.Instance.ShowBlur();
}
}
private void OnDialogueCompleted(object owner)
{
if ((Object)owner == this)
{
_dialogueState.MarkAsCompleted();
if (_isRetriggerable)
_dialogueState.AllowRetrigger();
_isDialogueActive = false;
}
if (DialogueManager.Instance != null)
DialogueManager.Instance.OnDialogueCompleted -= OnDialogueCompleted;
}
private void OnDestroy()
{
if (DialogueManager.Instance != null)
DialogueManager.Instance.OnDialogueCompleted -= OnDialogueCompleted;
}
public void LookAtPlayer()
{
if (Player.Instance == null) return;
Vector3 lookAtPosition = Player.Instance.transform.position;
lookAtPosition.y = transform.position.y;
transform.LookAt(lookAtPosition);
}
}
}