using UnityEngine; namespace Unheimlich.Features.Hallucination { /// /// Fires a hallucination trigger when a specific AudioSource plays, finishes, or reaches a timestamp. /// Mirrors the pattern of ClueUnlockOnAudio but targets HallucinationManager. /// [RequireComponent(typeof(AudioSource))] public class HallucinationOnAudio : MonoBehaviour { public enum FireCondition { OnPlay, OnFinish, OnTimeReached } [Header("Audio Trigger")] [Tooltip("When to fire the hallucination effect")] [SerializeField] private FireCondition _fireCondition = FireCondition.OnPlay; [Tooltip("Playback time in seconds to reach before firing (only for OnTimeReached)")] [SerializeField] private float _triggerTime = 1f; [Header("Hallucination Payload")] [Tooltip("Amount of sanity to add when this fires (0 = no change)")] [SerializeField, Range(0f, 1f)] private float _insanityAmount = 0f; [Tooltip("Optional discrete hallucination event to fire")] [SerializeField] private HallucinationEvent _hallucinationEvent; [Header("Behaviour")] [Tooltip("Prevent firing more than once per Play Mode session")] [SerializeField] private bool _fireOnlyOnce = true; [Header("Debug")] [SerializeField] private bool _debugMode; private AudioSource _audioSource; private bool _hasFired; private bool _isMonitoring; private void Awake() { _audioSource = GetComponent(); } private void OnEnable() { _hasFired = false; _isMonitoring = false; if (_audioSource != null && _audioSource.isPlaying) StartMonitoring(); } private void Update() { if (!_isMonitoring || (_fireOnlyOnce && _hasFired)) return; if (_audioSource == null || !_audioSource.isPlaying) { if (_fireCondition == FireCondition.OnFinish) Execute(); _isMonitoring = false; return; } if (_fireCondition == FireCondition.OnTimeReached && _audioSource.time >= _triggerTime) Execute(); } /// /// Notify this component that the AudioSource has started playing. /// Wire this to whatever code or event drives the AudioSource. /// public void OnAudioPlay() { StartMonitoring(); if (_fireCondition == FireCondition.OnPlay) Execute(); } /// /// Resets the fired state so this can fire again. /// public void ResetFired() { _hasFired = false; _isMonitoring = false; } private void StartMonitoring() { _isMonitoring = true; } private void Execute() { if (_fireOnlyOnce && _hasFired) return; _hasFired = true; _isMonitoring = false; if (HallucinationManager.Instance == null) { Debug.LogError("[HallucinationOnAudio] HallucinationManager not found!", this); return; } if (_insanityAmount > 0f) HallucinationManager.Instance.AddInsanity(_insanityAmount); if (_hallucinationEvent != null) HallucinationManager.Instance.TriggerHallucinationEvent(_hallucinationEvent); if (_debugMode) Debug.Log($"[HallucinationOnAudio] Fired on '{_fireCondition}'. Sanity now: {HallucinationManager.Instance.SanityLevel:F2}", this); } } }