186 lines
5.7 KiB
C#
186 lines
5.7 KiB
C#
using UnityEngine;
|
|
using Unheimlich.Features.Dialogue.Data;
|
|
using Unheimlich.Features.Dialogue;
|
|
using Unheimlich.Features.Dialogue.UI;
|
|
|
|
namespace Unheimlich.Features.Dialogue
|
|
{
|
|
/// <summary>
|
|
/// Trigger zone that starts a dialogue sequence when player enters.
|
|
/// Supports pause/resume on exit/enter and optional one-time triggering.
|
|
/// </summary>
|
|
[RequireComponent(typeof(Collider))]
|
|
public class DialogueTriggerZone : MonoBehaviour
|
|
{
|
|
[Header("Dialogue Reference")]
|
|
[Tooltip("DialogueConversation to use for this trigger zone")]
|
|
[SerializeField] private DialogueConversation _conversation;
|
|
|
|
[Header("Trigger Settings")]
|
|
[Tooltip("Can the dialogue be retriggered after completion")]
|
|
[SerializeField] private bool _isRetriggerable = false;
|
|
[SerializeField] private bool _requirePlayerTag = true;
|
|
[SerializeField] private string _playerTag = "Player";
|
|
|
|
[Header("Distance Check")]
|
|
[Tooltip("Pause dialogue if player exits the trigger zone")]
|
|
[SerializeField] private bool _pauseOnExit = true;
|
|
|
|
[Header("Floating Word Anchor")]
|
|
[SerializeField] private Transform _floatingWordAnchor;
|
|
|
|
[Header("Animation Settings")]
|
|
[SerializeField] private DialogueAnimationSettings _animationSettings;
|
|
|
|
[Header("UI Reference")]
|
|
[Tooltip("Local DialogueUI for this trigger zone. Uses DialogueManager's UI if null")]
|
|
[SerializeField] private DialogueUI _localDialogueUI;
|
|
|
|
[Header("Blur Effect")]
|
|
[Tooltip("Enable blur effect when dialogue starts")]
|
|
[SerializeField] private bool _enableBlurEffect = true;
|
|
|
|
private bool _hasTriggered = false;
|
|
private Collider _triggerCollider;
|
|
private DialogueStateHandler _dialogueState;
|
|
|
|
private void Awake()
|
|
{
|
|
_triggerCollider = GetComponent<Collider>();
|
|
_dialogueState = new DialogueStateHandler(this);
|
|
|
|
if (!_triggerCollider.isTrigger)
|
|
{
|
|
Debug.LogWarning($"{gameObject.name}: Collider should be marked as Trigger!", this);
|
|
_triggerCollider.isTrigger = true;
|
|
}
|
|
|
|
if (_floatingWordAnchor == null)
|
|
_floatingWordAnchor = transform;
|
|
}
|
|
|
|
private void OnTriggerEnter(Collider other)
|
|
{
|
|
if (_requirePlayerTag && !other.CompareTag(_playerTag))
|
|
return;
|
|
|
|
if (_dialogueState.IsCompleted && !_isRetriggerable)
|
|
return;
|
|
|
|
if (_dialogueState.HasPausedDialogue)
|
|
{
|
|
_dialogueState.ResumeDialogue();
|
|
|
|
if (_enableBlurEffect && DialogueBlurEffectURP.Instance != null)
|
|
DialogueBlurEffectURP.Instance.ShowBlur();
|
|
}
|
|
else if (!_hasTriggered || (_isRetriggerable && _dialogueState.IsCompleted))
|
|
{
|
|
TriggerDialogue();
|
|
}
|
|
}
|
|
|
|
private void OnTriggerExit(Collider other)
|
|
{
|
|
if (_requirePlayerTag && !other.CompareTag(_playerTag))
|
|
return;
|
|
|
|
if (_pauseOnExit && DialogueManager.Instance != null && DialogueManager.Instance.IsDialogueActive)
|
|
{
|
|
if ((Object)DialogueManager.Instance.CurrentOwner == this)
|
|
{
|
|
_dialogueState.PauseDialogue();
|
|
|
|
if (_enableBlurEffect && DialogueBlurEffectURP.Instance != null)
|
|
DialogueBlurEffectURP.Instance.HideBlur();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void TriggerDialogue()
|
|
{
|
|
if (DialogueManager.Instance == null)
|
|
{
|
|
Debug.LogError("DialogueManager not found in scene!", this);
|
|
return;
|
|
}
|
|
|
|
if (_conversation == null)
|
|
{
|
|
Debug.LogError($"{gameObject.name}: No conversation assigned!", this);
|
|
return;
|
|
}
|
|
|
|
_hasTriggered = true;
|
|
|
|
if (_enableBlurEffect && DialogueBlurEffectURP.Instance != null)
|
|
{
|
|
DialogueBlurEffectURP.Instance.ShowBlur();
|
|
}
|
|
|
|
DialogueManager.Instance.StartConversation(
|
|
_conversation,
|
|
_floatingWordAnchor,
|
|
_animationSettings,
|
|
_localDialogueUI,
|
|
this
|
|
);
|
|
|
|
DialogueManager.Instance.OnDialogueCompleted += OnDialogueCompleted;
|
|
}
|
|
|
|
private void OnDialogueCompleted(object owner)
|
|
{
|
|
if ((Object)owner == this)
|
|
{
|
|
_dialogueState.MarkAsCompleted();
|
|
|
|
if (_isRetriggerable)
|
|
{
|
|
_hasTriggered = false;
|
|
_dialogueState.AllowRetrigger();
|
|
}
|
|
|
|
if (_enableBlurEffect && DialogueBlurEffectURP.Instance != null)
|
|
DialogueBlurEffectURP.Instance.HideBlur();
|
|
}
|
|
|
|
if (DialogueManager.Instance != null)
|
|
DialogueManager.Instance.OnDialogueCompleted -= OnDialogueCompleted;
|
|
}
|
|
|
|
public void ResetTrigger()
|
|
{
|
|
_hasTriggered = false;
|
|
_dialogueState.Reset();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (DialogueManager.Instance != null)
|
|
DialogueManager.Instance.OnDialogueCompleted -= OnDialogueCompleted;
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
Collider col = GetComponent<Collider>();
|
|
if (col != null)
|
|
{
|
|
Gizmos.color = _hasTriggered ? Color.gray : Color.yellow;
|
|
Gizmos.matrix = transform.localToWorldMatrix;
|
|
|
|
if (col is BoxCollider box)
|
|
Gizmos.DrawWireCube(box.center, box.size);
|
|
else if (col is SphereCollider sphere)
|
|
Gizmos.DrawWireSphere(sphere.center, sphere.radius);
|
|
}
|
|
|
|
if (_floatingWordAnchor != null)
|
|
{
|
|
Gizmos.color = Color.cyan;
|
|
Gizmos.DrawWireSphere(_floatingWordAnchor.position, 0.2f);
|
|
}
|
|
}
|
|
}
|
|
}
|