using Core; using Core.Lifecycle; using Input; using UnityEngine; using UnityEngine.UI; namespace Cinematics { public class SkipCinematic : ManagedBehaviour, ITouchInputConsumer { [Header("Configuration")] [SerializeField] private float holdDuration = 2.0f; [SerializeField] private Image radialProgressBar; private float _holdStartTime; private bool _isHolding; private bool _skipPerformed; public override int ManagedAwakePriority => 180; // Cinematic UI internal override void OnManagedStart() { // Reset the progress bar if (radialProgressBar != null) { radialProgressBar.fillAmount = 0f; } // Subscribe to CinematicsManager events now that boot is complete SubscribeToCinematicsEvents(); Logging.Debug("[SkipCinematic] Initialized"); } protected override void OnDestroy() { base.OnDestroy(); // Clean up subscriptions UnsubscribeFromCinematicsEvents(); } private void SubscribeToCinematicsEvents() { if (CinematicsManager.Instance == null) return; // First unsubscribe to prevent duplicate subscriptions UnsubscribeFromCinematicsEvents(); // Now subscribe CinematicsManager.Instance.OnCinematicStarted += HandleCinematicStarted; CinematicsManager.Instance.OnCinematicStopped += HandleCinematicStopped; // Check if a cinematic is already playing if (CinematicsManager.Instance.IsCinematicPlaying) HandleCinematicStarted(); Logging.Debug("[SkipCinematic] Subscribed to cinematics events"); } private void UnsubscribeFromCinematicsEvents() { if (CinematicsManager.Instance != null) { CinematicsManager.Instance.OnCinematicStarted -= HandleCinematicStarted; CinematicsManager.Instance.OnCinematicStopped -= HandleCinematicStopped; Logging.Debug("[SkipCinematic] Unsubscribed from cinematics events"); } // If still registered as an input override consumer, unregister if (InputManager.Instance != null) { InputManager.Instance.UnregisterOverrideConsumer(this); Logging.Debug("[SkipCinematic] Unregistered as input override consumer"); } } private void HandleCinematicStarted() { if (InputManager.Instance != null) { InputManager.Instance.RegisterOverrideConsumer(this); } } private void HandleCinematicStopped() { if (InputManager.Instance != null) { InputManager.Instance.UnregisterOverrideConsumer(this); } } void Update() { // Only process while cinematic is playing and we're holding if (_isHolding && CinematicsManager.Instance.IsCinematicPlaying) { float holdTime = Time.time - _holdStartTime; float progress = Mathf.Clamp01(holdTime / holdDuration); // Update progress bar if (radialProgressBar != null) { radialProgressBar.fillAmount = progress; } // Check if we've held long enough to skip if (progress >= 1.0f && !_skipPerformed) { _skipPerformed = true; DoSkipCinematic(); } } } private void DoSkipCinematic() { CinematicsManager.Instance.SkipCurrentCinematic(); Logging.Debug("Cinematic skipped via touch hold"); // Reset UI if (radialProgressBar != null) { radialProgressBar.fillAmount = 0f; } // Remember to clear up input override InputManager.Instance.UnregisterOverrideConsumer(this); } #region ITouchInputConsumer Implementation public void OnTap(Vector2 position) { // Not using tap for skipping } public void OnHoldStart(Vector2 position) { // Start tracking hold time _isHolding = true; _skipPerformed = false; _holdStartTime = Time.time; Logging.Debug("Starting cinematic skip gesture"); } public void OnHoldMove(Vector2 position) { // Hold movement is tracked in Update method } public void OnHoldEnd(Vector2 position) { // Reset state when hold ends _isHolding = false; // Reset UI if (radialProgressBar != null) { radialProgressBar.fillAmount = 0f; } Logging.Debug("Cinematic skip gesture canceled"); } #endregion } }