using System; using Nox.Core; using UnityEngine; using UnityEngine.UI; namespace Nox.Game.UI { public class ScreenFadeTransition : MonoBehaviour, ISceneTransition { private enum FadeState { Idle, FadingOut, FadingIn } private const float DefaultFadeDuration = 0.3f; private const int CanvasSortOrder = 999; private CanvasGroup canvasGroup; private FadeState fadeState = FadeState.Idle; private float fadeTimer; private float fadeDuration = DefaultFadeDuration; private Action onFadeComplete; public bool IsTransitioning => fadeState != FadeState.Idle; public void Awake() { DontDestroyOnLoad(gameObject); CreateFadeCanvas(); canvasGroup.alpha = 0f; canvasGroup.blocksRaycasts = false; } public void FadeOut(Action onComplete = null) { if(fadeState == FadeState.FadingOut) { return; } onFadeComplete = onComplete; fadeState = FadeState.FadingOut; fadeTimer = 0f; canvasGroup.blocksRaycasts = true; } public void FadeIn(Action onComplete = null) { if(fadeState == FadeState.FadingIn) { return; } onFadeComplete = onComplete; fadeState = FadeState.FadingIn; fadeTimer = 0f; } public void Update() { if(fadeState == FadeState.Idle) { return; } fadeTimer += Time.unscaledDeltaTime; float t = Mathf.Clamp01(fadeTimer / fadeDuration); switch(fadeState) { case FadeState.FadingOut: canvasGroup.alpha = t; if(t >= 1f) { CompleteFade(); } break; case FadeState.FadingIn: canvasGroup.alpha = 1f - t; if(t >= 1f) { canvasGroup.blocksRaycasts = false; CompleteFade(); } break; } } private void CompleteFade() { fadeState = FadeState.Idle; fadeTimer = 0f; var callback = onFadeComplete; onFadeComplete = null; callback?.Invoke(); } private void CreateFadeCanvas() { var canvasObject = new GameObject("FadeCanvas"); canvasObject.transform.SetParent(transform); var canvas = canvasObject.AddComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvas.sortingOrder = CanvasSortOrder; canvasObject.AddComponent(); canvasGroup = canvasObject.AddComponent(); var imageObject = new GameObject("FadeImage"); imageObject.transform.SetParent(canvasObject.transform, false); var image = imageObject.AddComponent(); image.color = Color.black; image.raycastTarget = true; var rectTransform = image.rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; } } }