308 lines
9.0 KiB
C#
308 lines
9.0 KiB
C#
using System;
|
|
using System.Threading;
|
|
using BriarQueen.Framework.Coordinators.Events;
|
|
using BriarQueen.Framework.Events.UI;
|
|
using BriarQueen.Framework.Managers.Audio;
|
|
using BriarQueen.Framework.Managers.Interaction;
|
|
using BriarQueen.Framework.Managers.IO;
|
|
using BriarQueen.Framework.Managers.UI.Base;
|
|
using BriarQueen.Framework.Managers.UI.Events;
|
|
using BriarQueen.Framework.Services.Game;
|
|
using Cysharp.Threading.Tasks;
|
|
using PrimeTween;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using VContainer;
|
|
|
|
namespace BriarQueen.UI.Menus
|
|
{
|
|
public class PauseMenuWindow : MonoBehaviour, IUIWindow
|
|
{
|
|
[Header("Root UI")]
|
|
[SerializeField]
|
|
private CanvasGroup _canvasGroup;
|
|
|
|
[SerializeField]
|
|
private RectTransform _windowRect;
|
|
|
|
[Header("Buttons")]
|
|
[SerializeField]
|
|
private Button _resumeButton;
|
|
|
|
[SerializeField]
|
|
private Button _saveButton;
|
|
|
|
[SerializeField]
|
|
private Button _settingsButton;
|
|
|
|
[SerializeField]
|
|
private Button _exitButton;
|
|
|
|
[SerializeField]
|
|
private Button _quitToDesktopButton;
|
|
|
|
[Header("Tween Settings")]
|
|
[SerializeField]
|
|
private TweenSettings _tweenSettings = new()
|
|
{
|
|
duration = 0.25f,
|
|
ease = Ease.OutQuad,
|
|
useUnscaledTime = true
|
|
};
|
|
|
|
[Header("Scale")]
|
|
[SerializeField]
|
|
private float _hiddenScale = 0.85f;
|
|
|
|
[Header("Internal")]
|
|
[SerializeField]
|
|
private GraphicRaycaster _graphicRaycaster;
|
|
|
|
private AudioManager _audioManager;
|
|
|
|
private CancellationTokenSource _cts;
|
|
|
|
private EventCoordinator _eventCoordinator;
|
|
private GameService _gameService;
|
|
private InteractManager _interactManager;
|
|
private SaveManager _saveManager;
|
|
|
|
private Sequence _sequence;
|
|
|
|
public bool IsModal => true;
|
|
|
|
public WindowType WindowType => WindowType.PauseMenuWindow;
|
|
|
|
private void Awake()
|
|
{
|
|
// Start hidden by default
|
|
if (_canvasGroup != null)
|
|
{
|
|
_canvasGroup.alpha = 0f;
|
|
_canvasGroup.blocksRaycasts = false;
|
|
_canvasGroup.interactable = false;
|
|
}
|
|
|
|
if (_windowRect != null)
|
|
_windowRect.localScale = Vector3.one * _hiddenScale;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (_resumeButton != null) _resumeButton.onClick.AddListener(OnResumeButtonClick);
|
|
if (_saveButton != null) _saveButton.onClick.AddListener(OnSaveButtonClick);
|
|
if (_settingsButton != null) _settingsButton.onClick.AddListener(OnSettingsButtonClick);
|
|
if (_exitButton != null) _exitButton.onClick.AddListener(OnExitButtonClick);
|
|
if (_quitToDesktopButton != null) _quitToDesktopButton.onClick.AddListener(OnQuitToDesktopButtonClick);
|
|
|
|
_interactManager.AddUIRaycaster(_graphicRaycaster);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (_resumeButton != null) _resumeButton.onClick.RemoveListener(OnResumeButtonClick);
|
|
if (_saveButton != null) _saveButton.onClick.RemoveListener(OnSaveButtonClick);
|
|
if (_settingsButton != null) _settingsButton.onClick.RemoveListener(OnSettingsButtonClick);
|
|
if (_exitButton != null) _exitButton.onClick.RemoveListener(OnExitButtonClick);
|
|
if (_quitToDesktopButton != null) _quitToDesktopButton.onClick.RemoveListener(OnQuitToDesktopButtonClick);
|
|
|
|
_interactManager.RemoveUIRaycaster(_graphicRaycaster);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
StopAndResetCancellation();
|
|
}
|
|
|
|
public async UniTask Show()
|
|
{
|
|
if (_canvasGroup == null || _windowRect == null)
|
|
{
|
|
Debug.LogError("[PauseMenuWindow] Missing CanvasGroup or WindowRect reference.");
|
|
gameObject.SetActive(true);
|
|
return;
|
|
}
|
|
|
|
StopAndResetCancellation();
|
|
|
|
gameObject.SetActive(true);
|
|
|
|
_canvasGroup.alpha = 0f;
|
|
_canvasGroup.blocksRaycasts = false;
|
|
_canvasGroup.interactable = false;
|
|
|
|
_windowRect.localScale = Vector3.one * _hiddenScale;
|
|
|
|
var alpha = new TweenSettings<float>
|
|
{
|
|
startValue = 0f,
|
|
endValue = 1f,
|
|
settings = _tweenSettings
|
|
};
|
|
|
|
var scale = new TweenSettings<Vector3>
|
|
{
|
|
startValue = Vector3.one * _hiddenScale,
|
|
endValue = Vector3.one,
|
|
settings = _tweenSettings
|
|
};
|
|
|
|
_sequence = Sequence.Create(useUnscaledTime: true)
|
|
.Group(Tween.Alpha(_canvasGroup, alpha))
|
|
.Group(Tween.Scale(_windowRect, scale));
|
|
|
|
try
|
|
{
|
|
await _sequence.ToUniTask(cancellationToken: _cts.Token);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
return;
|
|
}
|
|
finally
|
|
{
|
|
_sequence = default;
|
|
}
|
|
|
|
_canvasGroup.alpha = 1f;
|
|
_windowRect.localScale = Vector3.one;
|
|
|
|
_canvasGroup.blocksRaycasts = true;
|
|
_canvasGroup.interactable = true;
|
|
}
|
|
|
|
public async UniTask Hide()
|
|
{
|
|
if (_canvasGroup == null || _windowRect == null)
|
|
{
|
|
gameObject.SetActive(false);
|
|
return;
|
|
}
|
|
|
|
StopAndResetCancellation();
|
|
|
|
// Block clicks immediately
|
|
_canvasGroup.blocksRaycasts = false;
|
|
_canvasGroup.interactable = false;
|
|
|
|
var alpha = new TweenSettings<float>
|
|
{
|
|
startValue = _canvasGroup.alpha,
|
|
endValue = 0f,
|
|
settings = _tweenSettings
|
|
};
|
|
|
|
var scale = new TweenSettings<Vector3>
|
|
{
|
|
startValue = _windowRect.localScale,
|
|
endValue = Vector3.one * _hiddenScale,
|
|
settings = _tweenSettings
|
|
};
|
|
|
|
_sequence = Sequence.Create(useUnscaledTime: true)
|
|
.Group(Tween.Alpha(_canvasGroup, alpha))
|
|
.Group(Tween.Scale(_windowRect, scale));
|
|
|
|
try
|
|
{
|
|
await _sequence.ToUniTask(cancellationToken: _cts.Token);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
return;
|
|
}
|
|
finally
|
|
{
|
|
_sequence = default;
|
|
}
|
|
|
|
_canvasGroup.alpha = 0f;
|
|
_windowRect.localScale = Vector3.one * _hiddenScale;
|
|
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
[Inject]
|
|
public void Construct(EventCoordinator eventCoordinator, SaveManager saveManager, GameService gameService,
|
|
InteractManager interactManager, AudioManager audioManager)
|
|
{
|
|
_eventCoordinator = eventCoordinator;
|
|
_saveManager = saveManager;
|
|
_gameService = gameService;
|
|
_interactManager = interactManager;
|
|
_audioManager = audioManager;
|
|
}
|
|
|
|
private void StopAndResetCancellation()
|
|
{
|
|
if (_sequence.isAlive)
|
|
_sequence.Stop();
|
|
|
|
if (_cts != null)
|
|
{
|
|
try
|
|
{
|
|
_cts.Cancel();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
_cts.Dispose();
|
|
_cts = null;
|
|
}
|
|
|
|
_cts = new CancellationTokenSource();
|
|
}
|
|
|
|
private void OnResumeButtonClick()
|
|
{
|
|
_eventCoordinator?.Publish(new PauseButtonClickedEvent());
|
|
}
|
|
|
|
private void OnSaveButtonClick()
|
|
{
|
|
SaveGame().Forget();
|
|
}
|
|
|
|
private void OnSettingsButtonClick()
|
|
{
|
|
_eventCoordinator.Publish(new UIToggleSettingsWindow(true));
|
|
}
|
|
|
|
private void OnExitButtonClick()
|
|
{
|
|
_eventCoordinator.Publish(new FadeEvent(false, 1f));
|
|
ExitButtonInternal().Forget();
|
|
}
|
|
|
|
private async UniTask ExitButtonInternal()
|
|
{
|
|
await UniTask.Delay(TimeSpan.FromSeconds(1));
|
|
_audioManager.StopAllAudio();
|
|
await SaveGame();
|
|
_eventCoordinator.Publish(new PauseButtonClickedEvent());
|
|
await _gameService.LoadMainMenu();
|
|
}
|
|
|
|
private void OnQuitToDesktopButtonClick()
|
|
{
|
|
QuitButtonInternal().Forget();
|
|
}
|
|
|
|
private async UniTask QuitButtonInternal()
|
|
{
|
|
_eventCoordinator.Publish(new FadeEvent(false, 1f));
|
|
await UniTask.Delay(TimeSpan.FromSeconds(1));
|
|
await SaveGame();
|
|
_gameService.QuitGame();
|
|
}
|
|
|
|
private async UniTask SaveGame()
|
|
{
|
|
if (_saveManager == null) return;
|
|
await _saveManager.SaveGameDataLatest();
|
|
// TODO: Saved feedback popup/toast
|
|
}
|
|
}
|
|
} |