using System; using System.Collections; using UnityEngine; using UnityEngine.UI; namespace OctoCore.Navigation { /// /// Handles fade in/out transitions for scene loading and teleportation. /// public class OctoSceneFade : MonoBehaviour { public static OctoSceneFade Instance { get; private set; } public Action OnFadeIn; public Action OnFadeOut; private Canvas _canvas; private Image _fadeImage; private IEnumerator fadeOutCoroutine; private IEnumerator fadeInCoroutine; private void Awake() { Instance = this; } /// /// Initialize the fade canvas and image. /// public void Initialize() { // Create canvas _canvas = gameObject.AddComponent(); _canvas.renderMode = RenderMode.ScreenSpaceOverlay; _canvas.sortingOrder = 9999; gameObject.AddComponent(); gameObject.AddComponent(); // Create fade image GameObject imageObj = new GameObject("FadeImage"); imageObj.transform.SetParent(transform); _fadeImage = imageObj.AddComponent(); _fadeImage.color = new Color(0, 0, 0, 0); RectTransform rt = _fadeImage.GetComponent(); rt.anchorMin = Vector2.zero; rt.anchorMax = Vector2.one; rt.sizeDelta = rt.anchoredPosition = Vector2.zero; _canvas.enabled = false; } /// /// Fade out to specified color over duration. /// public void FadeOut(float duration, Color color) { if (fadeOutCoroutine == null) { if (fadeInCoroutine != null) StopCoroutine(fadeInCoroutine); StartCoroutine(fadeOutCoroutine = FadeOutCoroutine(duration, color)); OnFadeOut?.Invoke(); } } /// /// Fade in from current color to transparent over duration. /// public void FadeIn(float duration) { if (fadeInCoroutine == null) { if (fadeOutCoroutine != null) StopCoroutine(fadeOutCoroutine); StartCoroutine(fadeInCoroutine = FadeInCoroutine(duration)); OnFadeIn?.Invoke(); } } private IEnumerator FadeOutCoroutine(float duration, Color color) { _canvas.enabled = true; Color startColor = new Color(color.r, color.g, color.b, 0); Color endColor = new Color(color.r, color.g, color.b, 1); for (float t = 0; t < duration; t += Time.unscaledDeltaTime) { float normalizedTime = Mathf.Clamp01(t / duration); _fadeImage.color = Color.Lerp(startColor, endColor, normalizedTime); yield return new WaitForEndOfFrame(); } _fadeImage.color = endColor; fadeOutCoroutine = null; } /// /// Fade in from current color to transparent over duration. /// private IEnumerator FadeInCoroutine(float duration) { Color startColor = _fadeImage.color; if (startColor != Color.clear) { Color endColor = new Color(startColor.r, startColor.g, startColor.b, 0); for (float t = 0; t < duration; t += Time.unscaledDeltaTime) { float normalizedTime = Mathf.Clamp01(t / duration); _fadeImage.color = Color.Lerp(startColor, endColor, normalizedTime); yield return new WaitForEndOfFrame(); } _fadeImage.color = endColor; _canvas.enabled = false; } fadeInCoroutine = null; } } }