205 lines
5.7 KiB
C#
205 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using BriarQueen.Framework.Services.Game;
|
|
using BriarQueen.Game.Cinematics.Data;
|
|
using Cysharp.Threading.Tasks;
|
|
using NaughtyAttributes;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using UnityEngine.UI;
|
|
using VContainer;
|
|
|
|
namespace BriarQueen.Game.Cinematics
|
|
{
|
|
public class SplashScreens : MonoBehaviour
|
|
{
|
|
[SerializeField]
|
|
[ReorderableList]
|
|
private List<CinematicPanel> _splashScreens = new();
|
|
|
|
[SerializeField]
|
|
private Image _activeSplashScreen;
|
|
|
|
[Header("Playback")]
|
|
[Tooltip("Small fade for polish. Set to 0 for hard cuts.")]
|
|
[SerializeField]
|
|
private float _fadeDuration = 0.15f;
|
|
|
|
[SerializeField]
|
|
private bool _skipInvalidPanels = true;
|
|
|
|
private CancellationTokenSource _cts;
|
|
private GameService _gameService;
|
|
private bool _isPlaying;
|
|
|
|
[Inject]
|
|
public void Construct(GameService gameService)
|
|
{
|
|
_gameService = gameService;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
Stop();
|
|
}
|
|
|
|
public void Play()
|
|
{
|
|
if (_isPlaying)
|
|
return;
|
|
|
|
Debug.Log("[SplashScreens] Playing splash screens.");
|
|
|
|
_isPlaying = true;
|
|
_cts?.Dispose();
|
|
_cts = new CancellationTokenSource();
|
|
|
|
RunSequence(_cts.Token).Forget();
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
if (!_isPlaying)
|
|
return;
|
|
|
|
_isPlaying = false;
|
|
|
|
try
|
|
{
|
|
_cts?.Cancel();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
finally
|
|
{
|
|
_cts?.Dispose();
|
|
_cts = null;
|
|
}
|
|
}
|
|
|
|
private async UniTaskVoid RunSequence(CancellationToken token)
|
|
{
|
|
try
|
|
{
|
|
Debug.Log("[SplashScreens] Splash screen sequence started.");
|
|
|
|
if (_activeSplashScreen == null)
|
|
{
|
|
Debug.LogWarning("[SplashScreens] Active splash Image is not assigned.");
|
|
await EndSplashScreens();
|
|
return;
|
|
}
|
|
|
|
var cg = _activeSplashScreen.GetComponent<CanvasGroup>();
|
|
if (cg == null)
|
|
cg = _activeSplashScreen.gameObject.AddComponent<CanvasGroup>();
|
|
|
|
cg.alpha = 0f;
|
|
_activeSplashScreen.enabled = true;
|
|
|
|
if (_splashScreens == null || _splashScreens.Count == 0)
|
|
{
|
|
Debug.LogWarning("[SplashScreens] No splash panels configured.");
|
|
await EndSplashScreens();
|
|
return;
|
|
}
|
|
|
|
for (var i = 0; i < _splashScreens.Count; i++)
|
|
{
|
|
token.ThrowIfCancellationRequested();
|
|
|
|
var panel = _splashScreens[i];
|
|
if (panel == null || panel.CinematicImage == null)
|
|
{
|
|
if (_skipInvalidPanels)
|
|
continue;
|
|
|
|
Debug.LogWarning($"[SplashScreens] Splash panel at index {i} is null or missing image.");
|
|
continue;
|
|
}
|
|
|
|
_activeSplashScreen.sprite = panel.CinematicImage;
|
|
|
|
if (_fadeDuration > 0f)
|
|
await FadeTo(cg, 1f, _fadeDuration, token);
|
|
else
|
|
cg.alpha = 1f;
|
|
|
|
var hold = Mathf.Max(0f, panel.DisplayTime);
|
|
if (hold > 0f)
|
|
await UniTask.Delay(TimeSpan.FromSeconds(hold), cancellationToken: token);
|
|
|
|
if (_fadeDuration > 0f)
|
|
await FadeTo(cg, 0f, _fadeDuration, token);
|
|
else
|
|
cg.alpha = 0f;
|
|
}
|
|
|
|
await EndSplashScreens();
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"[SplashScreens] Sequence failed: {ex}");
|
|
|
|
try
|
|
{
|
|
await EndSplashScreens();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
_isPlaying = false;
|
|
}
|
|
}
|
|
|
|
private async UniTask FadeTo(CanvasGroup cg, float target, float duration, CancellationToken token)
|
|
{
|
|
var start = cg.alpha;
|
|
|
|
if (Mathf.Approximately(start, target))
|
|
{
|
|
cg.alpha = target;
|
|
return;
|
|
}
|
|
|
|
var t = 0f;
|
|
while (t < duration)
|
|
{
|
|
token.ThrowIfCancellationRequested();
|
|
|
|
t += Time.deltaTime;
|
|
var p = Mathf.Clamp01(t / duration);
|
|
cg.alpha = Mathf.Lerp(start, target, p);
|
|
|
|
await UniTask.NextFrame(token);
|
|
}
|
|
|
|
cg.alpha = target;
|
|
}
|
|
|
|
private async UniTask EndSplashScreens()
|
|
{
|
|
if (_gameService != null)
|
|
{
|
|
await _gameService.LoadUIAndMainMenuScene();
|
|
}
|
|
else
|
|
{
|
|
Debug.LogWarning("[SplashScreens] GameService is null; cannot load UI/MainMenu scene.");
|
|
}
|
|
|
|
const string bootstrapSceneName = "00_Bootstrap";
|
|
var scene = SceneManager.GetSceneByName(bootstrapSceneName);
|
|
if (scene.IsValid() && scene.isLoaded)
|
|
await SceneManager.UnloadSceneAsync(bootstrapSceneName);
|
|
}
|
|
}
|
|
} |