213 lines
5.5 KiB
C#
213 lines
5.5 KiB
C#
using System;
|
|
using System.Threading;
|
|
using BriarQueen.Framework.Coordinators.Events;
|
|
using BriarQueen.Framework.Events.UI;
|
|
using BriarQueen.Framework.Services.Subtitles;
|
|
using Cysharp.Threading.Tasks;
|
|
using PrimeTween;
|
|
using UnityEngine;
|
|
using VContainer;
|
|
|
|
namespace BriarQueen.UI.HUD
|
|
{
|
|
public class SubtitleUI : MonoBehaviour
|
|
{
|
|
[Header("UI")]
|
|
[SerializeField]
|
|
private InteractTextUI _interactTextUI;
|
|
|
|
[SerializeField]
|
|
private CanvasGroup _canvasGroup;
|
|
|
|
[Header("Tweens")]
|
|
[SerializeField]
|
|
private TweenSettings _tweenSettings = new()
|
|
{
|
|
duration = 0.2f,
|
|
ease = Ease.InOutSine,
|
|
useUnscaledTime = true
|
|
};
|
|
|
|
private EventCoordinator _eventCoordinator;
|
|
private SubtitleService _subtitleService;
|
|
private CancellationTokenSource _cancellationTokenSource;
|
|
private Sequence _sequence;
|
|
|
|
[Inject]
|
|
public void Construct(EventCoordinator eventCoordinator, SubtitleService subtitleService)
|
|
{
|
|
_eventCoordinator = eventCoordinator;
|
|
_subtitleService = subtitleService;
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
ApplyImmediate(string.Empty, false);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
_eventCoordinator?.Subscribe<SubtitleDisplayChangedEvent>(OnSubtitleDisplayChanged);
|
|
SyncFromService();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_eventCoordinator?.Unsubscribe<SubtitleDisplayChangedEvent>(OnSubtitleDisplayChanged);
|
|
StopTween();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
StopTween();
|
|
}
|
|
|
|
private void SyncFromService()
|
|
{
|
|
if (_subtitleService != null && _subtitleService.IsVisible)
|
|
{
|
|
ApplyImmediate(_subtitleService.CurrentText, true);
|
|
return;
|
|
}
|
|
|
|
ApplyImmediate(string.Empty, false);
|
|
}
|
|
|
|
private void OnSubtitleDisplayChanged(SubtitleDisplayChangedEvent eventData)
|
|
{
|
|
if (!eventData.Visible || string.IsNullOrWhiteSpace(eventData.Text))
|
|
{
|
|
HideSubtitle().Forget();
|
|
return;
|
|
}
|
|
|
|
ShowSubtitle(eventData.Text).Forget();
|
|
}
|
|
|
|
private async UniTaskVoid ShowSubtitle(string text)
|
|
{
|
|
if (_canvasGroup == null || _interactTextUI == null)
|
|
return;
|
|
|
|
StopTween();
|
|
|
|
_interactTextUI.SetText(text);
|
|
_canvasGroup.blocksRaycasts = false;
|
|
_canvasGroup.interactable = false;
|
|
|
|
_cancellationTokenSource = new CancellationTokenSource();
|
|
|
|
var tween = new TweenSettings<float>
|
|
{
|
|
startValue = _canvasGroup.alpha,
|
|
endValue = 1f,
|
|
settings = _tweenSettings
|
|
};
|
|
|
|
_sequence = Sequence.Create(useUnscaledTime: true)
|
|
.Group(Tween.Alpha(_canvasGroup, tween));
|
|
|
|
try
|
|
{
|
|
await _sequence.ToUniTask(cancellationToken: _cancellationTokenSource.Token);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
return;
|
|
}
|
|
finally
|
|
{
|
|
DisposeTweenState();
|
|
}
|
|
|
|
_canvasGroup.alpha = 1f;
|
|
}
|
|
|
|
private async UniTaskVoid HideSubtitle()
|
|
{
|
|
if (_canvasGroup == null || _interactTextUI == null)
|
|
return;
|
|
|
|
StopTween();
|
|
|
|
_cancellationTokenSource = new CancellationTokenSource();
|
|
|
|
var tween = new TweenSettings<float>
|
|
{
|
|
startValue = _canvasGroup.alpha,
|
|
endValue = 0f,
|
|
settings = _tweenSettings
|
|
};
|
|
|
|
_sequence = Sequence.Create(useUnscaledTime: true)
|
|
.Group(Tween.Alpha(_canvasGroup, tween));
|
|
|
|
try
|
|
{
|
|
await _sequence.ToUniTask(cancellationToken: _cancellationTokenSource.Token);
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
return;
|
|
}
|
|
finally
|
|
{
|
|
DisposeTweenState();
|
|
}
|
|
|
|
ApplyImmediate(string.Empty, false);
|
|
}
|
|
|
|
private void ApplyImmediate(string text, bool visible)
|
|
{
|
|
if (_interactTextUI != null)
|
|
{
|
|
if (visible)
|
|
_interactTextUI.SetText(text);
|
|
else
|
|
_interactTextUI.ClearText();
|
|
}
|
|
|
|
if (_canvasGroup == null)
|
|
return;
|
|
|
|
_canvasGroup.alpha = visible ? 1f : 0f;
|
|
_canvasGroup.blocksRaycasts = false;
|
|
_canvasGroup.interactable = false;
|
|
}
|
|
|
|
private void StopTween()
|
|
{
|
|
if (_sequence.isAlive)
|
|
_sequence.Stop();
|
|
|
|
_sequence = default;
|
|
|
|
if (_cancellationTokenSource == null)
|
|
return;
|
|
|
|
try
|
|
{
|
|
_cancellationTokenSource.Cancel();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
_cancellationTokenSource.Dispose();
|
|
_cancellationTokenSource = null;
|
|
}
|
|
|
|
private void DisposeTweenState()
|
|
{
|
|
_sequence = default;
|
|
|
|
if (_cancellationTokenSource == null)
|
|
return;
|
|
|
|
_cancellationTokenSource.Dispose();
|
|
_cancellationTokenSource = null;
|
|
}
|
|
}
|
|
}
|