Hallucination system
This commit is contained in:
@@ -53,8 +53,35 @@ namespace Unheimlich.Features.Dialogue
|
||||
private float _autoCloseTimer = 0f;
|
||||
private bool _isWaitingForAutoClose = false;
|
||||
|
||||
protected override void OnAwake()
|
||||
protected override void OnAwake() { }
|
||||
|
||||
protected override void OnEnabled()
|
||||
{
|
||||
// With Scene Reload disabled, Start() doesn't run again each session.
|
||||
// We recreate the focus system to clear any stale locked state (_isFocusLocked,
|
||||
// _focusTimer, _currentFocusedHandler) that may have carried over.
|
||||
if (_focusSystem != null)
|
||||
{
|
||||
_mainCamera = Camera.main;
|
||||
_focusSystem = new DialogueFocusSystem(
|
||||
this,
|
||||
_mainCamera,
|
||||
PlayerController.Instance?.CameraEffects,
|
||||
_choiceLayer,
|
||||
_focusRange,
|
||||
_focusTime,
|
||||
_raycastInterval,
|
||||
_recoveryDuration,
|
||||
_focusRetentionTime,
|
||||
_fallbackShakeIntensity
|
||||
);
|
||||
_focusSystem.OnChoiceMade += (choice) => OnChoiceMade?.Invoke(choice);
|
||||
|
||||
// Also reset dialogue state in case we exited mid-dialogue
|
||||
IsInDialogue = false;
|
||||
_isWaitingForAutoClose = false;
|
||||
_autoCloseTimer = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
@@ -82,6 +109,13 @@ namespace Unheimlich.Features.Dialogue
|
||||
if (!IsInDialogue)
|
||||
return;
|
||||
|
||||
if (_activeDialogueUI == null)
|
||||
{
|
||||
Debug.LogError("[DialogueManager] IsInDialogue is true but _activeDialogueUI is null. Forcing dialogue end.", this);
|
||||
IsInDialogue = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_activeDialogueUI.AreChoicesVisible())
|
||||
{
|
||||
if (_isWaitingForAutoClose && _currentNode != null && _currentNode.AutoCloseDelay > 0f)
|
||||
@@ -142,6 +176,12 @@ namespace Unheimlich.Features.Dialogue
|
||||
_activeDialogueUI = customDialogueUI;
|
||||
CurrentOwner = owner;
|
||||
|
||||
if (_activeDialogueUI == null)
|
||||
{
|
||||
Debug.LogError("[DialogueManager] StartConversation called with no DialogueUI. Assign a Local Dialogue UI on the DialogueTriggerZone that triggered this conversation.", this);
|
||||
return;
|
||||
}
|
||||
|
||||
ShowCurrentNode();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using UnityEngine;
|
||||
using Unheimlich.Features.Dialogue.Data;
|
||||
using Unheimlich.Features.Dialogue;
|
||||
using Unheimlich.Features.Dialogue.UI;
|
||||
using Unheimlich.Core.Events;
|
||||
|
||||
namespace Unheimlich.Features.Dialogue
|
||||
{
|
||||
@@ -9,9 +10,8 @@ namespace Unheimlich.Features.Dialogue
|
||||
/// 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
|
||||
{
|
||||
public class DialogueTriggerZone : TriggerZoneBase
|
||||
{
|
||||
[Header("Dialogue Reference")]
|
||||
[Tooltip("DialogueConversation to use for this trigger zone")]
|
||||
[SerializeField] private DialogueConversation _conversation;
|
||||
@@ -19,8 +19,8 @@ namespace Unheimlich.Features.Dialogue
|
||||
[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";
|
||||
|
||||
protected override bool IsRetriggerable => _isRetriggerable;
|
||||
|
||||
[Header("Distance Check")]
|
||||
[Tooltip("Pause dialogue if player exits the trigger zone")]
|
||||
@@ -41,29 +41,19 @@ namespace Unheimlich.Features.Dialogue
|
||||
[SerializeField] private bool _enableBlurEffect = true;
|
||||
|
||||
private bool _hasTriggered = false;
|
||||
private Collider _triggerCollider;
|
||||
private DialogueStateHandler _dialogueState;
|
||||
|
||||
private void Awake()
|
||||
protected override void Awake()
|
||||
{
|
||||
_triggerCollider = GetComponent<Collider>();
|
||||
base.Awake();
|
||||
_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)
|
||||
protected override void OnPlayerEntered(Collider playerCollider)
|
||||
{
|
||||
if (_requirePlayerTag && !other.CompareTag(_playerTag))
|
||||
return;
|
||||
|
||||
if (_dialogueState.IsCompleted && !_isRetriggerable)
|
||||
return;
|
||||
|
||||
@@ -80,11 +70,8 @@ namespace Unheimlich.Features.Dialogue
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
protected override void OnPlayerExited(Collider playerCollider)
|
||||
{
|
||||
if (_requirePlayerTag && !other.CompareTag(_playerTag))
|
||||
return;
|
||||
|
||||
if (_pauseOnExit && DialogueManager.Instance != null && DialogueManager.Instance.IsDialogueActive)
|
||||
{
|
||||
if ((Object)DialogueManager.Instance.CurrentOwner == this)
|
||||
@@ -153,6 +140,7 @@ namespace Unheimlich.Features.Dialogue
|
||||
{
|
||||
_hasTriggered = false;
|
||||
_dialogueState.Reset();
|
||||
ResetZone();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -161,20 +149,14 @@ namespace Unheimlich.Features.Dialogue
|
||||
DialogueManager.Instance.OnDialogueCompleted -= OnDialogueCompleted;
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (_localDialogueUI == null)
|
||||
Debug.LogWarning($"[DialogueTriggerZone] '{gameObject.name}' has no Local Dialogue UI assigned. Assign the appropriate DialogueUI prefab variant (World, NPC, Room, Screen, etc.).", this);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -253,7 +253,8 @@ namespace Unheimlich.Features.Dialogue.UI
|
||||
{
|
||||
if (!_positionCaptured)
|
||||
{
|
||||
_startLocalPos = transform.localPosition;
|
||||
// Subtract shake offset to get the clean base position, not the shaken one
|
||||
_startLocalPos = transform.localPosition - _shakeOffset;
|
||||
_positionCaptured = true;
|
||||
|
||||
LeanTween.cancel(gameObject);
|
||||
@@ -516,13 +517,15 @@ namespace Unheimlich.Features.Dialogue.UI
|
||||
|
||||
ResetSketchFade();
|
||||
|
||||
// Reset position capture and restart shake immediately — don't rely on a LeanTween
|
||||
// callback for this, since stale tween IDs (Domain Reload disabled) can silently
|
||||
// drop callbacks, leaving some words permanently non-shaking.
|
||||
_positionCaptured = false;
|
||||
StartOrganicShake();
|
||||
|
||||
TweenHelper.MoveLocal(gameObject, _startLocalPos, duration, () => {
|
||||
_positionCaptured = false;
|
||||
|
||||
if (DialogueManager.Instance != null)
|
||||
DialogueManager.Instance.UnlockFocus();
|
||||
|
||||
StartOrganicShake();
|
||||
}, LeanTweenType.easeOutQuad);
|
||||
|
||||
transform.localScale = Vector3.one * _originalScale;
|
||||
|
||||
Reference in New Issue
Block a user