142 lines
4.5 KiB
C#
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);
|
|
}
|
|
}
|
|
} |