First commit for private source control. Older commits available on Github.
This commit is contained in:
282
Assets/Scripts/UI/HUD/HUDContainer.cs
Normal file
282
Assets/Scripts/UI/HUD/HUDContainer.cs
Normal file
@@ -0,0 +1,282 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using BriarQueen.Framework.Managers.UI;
|
||||
using BriarQueen.Framework.Managers.UI.Base;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using PrimeTween;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.UI.HUD
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimal HUD holder:
|
||||
/// - Registers itself with UIManager
|
||||
/// - Handles HUD visibility (alpha tween only)
|
||||
/// </summary>
|
||||
public class HUDContainer : MonoBehaviour, IHud
|
||||
{
|
||||
private const float DISPLAY_TIME = 4f;
|
||||
|
||||
[Header("UI")]
|
||||
[SerializeField]
|
||||
private CursorTooltip _cursorTooltip;
|
||||
[SerializeField]
|
||||
private InteractTextUI _interactText;
|
||||
|
||||
[Header("Inventory")]
|
||||
[SerializeField]
|
||||
private InventoryBar _inventoryBar;
|
||||
|
||||
[Header("Components")]
|
||||
[SerializeField]
|
||||
private CanvasGroup _mainCanvasGroup;
|
||||
|
||||
|
||||
[SerializeField]
|
||||
private CanvasGroup _interactTextCanvasGroup;
|
||||
|
||||
[Header("Tweens")]
|
||||
[SerializeField]
|
||||
private TweenSettings _tweenSettings = new()
|
||||
{
|
||||
duration = 0.2f,
|
||||
ease = Ease.InOutSine,
|
||||
useUnscaledTime = true
|
||||
};
|
||||
|
||||
[SerializeField]
|
||||
private GraphicRaycaster _graphicRaycaster;
|
||||
public GraphicRaycaster Raycaster => _graphicRaycaster;
|
||||
|
||||
private CancellationTokenSource _cancellationTokenSource;
|
||||
|
||||
private Sequence _hudSequence;
|
||||
private CancellationTokenSource _interactCancellationTokenSource;
|
||||
|
||||
private Sequence _interactErrorSequence;
|
||||
private UIManager _uiManager;
|
||||
|
||||
public CursorTooltip CursorTooltip => _cursorTooltip;
|
||||
public InventoryBar InventoryBar => _inventoryBar;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_mainCanvasGroup != null)
|
||||
{
|
||||
_mainCanvasGroup.alpha = 1f;
|
||||
_mainCanvasGroup.interactable = true;
|
||||
_mainCanvasGroup.blocksRaycasts = true;
|
||||
}
|
||||
|
||||
if (_interactTextCanvasGroup != null)
|
||||
{
|
||||
_interactTextCanvasGroup.alpha = 0f;
|
||||
_interactTextCanvasGroup.blocksRaycasts = false;
|
||||
_interactTextCanvasGroup.interactable = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
StopTween();
|
||||
|
||||
StopInteractErrorTween();
|
||||
}
|
||||
|
||||
[Inject]
|
||||
public void Construct(UIManager uiManager)
|
||||
{
|
||||
_uiManager = uiManager;
|
||||
}
|
||||
|
||||
// --------------------
|
||||
// Visibility
|
||||
// --------------------
|
||||
|
||||
public async UniTask DisplayInteractText(string interactText)
|
||||
{
|
||||
if (_interactTextCanvasGroup == null || _interactText == null)
|
||||
return;
|
||||
|
||||
// Cancel any in-flight error display and restart from current alpha.
|
||||
StopInteractErrorTween();
|
||||
|
||||
// Set text immediately.
|
||||
var text = interactText ?? string.Empty;
|
||||
|
||||
_interactText.SetText(text);
|
||||
|
||||
_interactCancellationTokenSource = new CancellationTokenSource();
|
||||
var token = _interactCancellationTokenSource.Token;
|
||||
|
||||
// Make sure it can show (but don't let it steal clicks).
|
||||
_interactTextCanvasGroup.blocksRaycasts = false;
|
||||
_interactTextCanvasGroup.interactable = false;
|
||||
|
||||
var fadeIn = new TweenSettings<float>
|
||||
{
|
||||
startValue = _interactTextCanvasGroup.alpha,
|
||||
endValue = 1f,
|
||||
settings = _tweenSettings
|
||||
};
|
||||
|
||||
var fadeOut = new TweenSettings<float>
|
||||
{
|
||||
startValue = 1f,
|
||||
endValue = 0f,
|
||||
settings = _tweenSettings
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
// Fade in
|
||||
_interactErrorSequence = Sequence.Create(useUnscaledTime: true)
|
||||
.Group(Tween.Alpha(_interactTextCanvasGroup, fadeIn));
|
||||
|
||||
await _interactErrorSequence.ToUniTask(cancellationToken: token);
|
||||
|
||||
_interactTextCanvasGroup.alpha = 1f;
|
||||
|
||||
// Hold
|
||||
if (DISPLAY_TIME > 0f)
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(DISPLAY_TIME), DelayType.UnscaledDeltaTime,
|
||||
cancellationToken: token);
|
||||
|
||||
// Fade out
|
||||
_interactErrorSequence = Sequence.Create(useUnscaledTime: true)
|
||||
.Group(Tween.Alpha(_interactTextCanvasGroup, fadeOut));
|
||||
|
||||
await _interactErrorSequence.ToUniTask(cancellationToken: token);
|
||||
|
||||
_interactTextCanvasGroup.alpha = 0f;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// If interrupted by a newer DisplayError call or destroy, just stop cleanly.
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_interactCancellationTokenSource != null)
|
||||
{
|
||||
_interactCancellationTokenSource.Dispose();
|
||||
_interactCancellationTokenSource = null;
|
||||
}
|
||||
|
||||
_interactErrorSequence = default;
|
||||
}
|
||||
}
|
||||
|
||||
public async UniTask Show()
|
||||
{
|
||||
if (_mainCanvasGroup == null)
|
||||
return;
|
||||
|
||||
StopTween();
|
||||
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
_mainCanvasGroup.blocksRaycasts = true;
|
||||
_mainCanvasGroup.interactable = true;
|
||||
|
||||
var alphaTween = new TweenSettings<float>
|
||||
{
|
||||
startValue = _mainCanvasGroup.alpha,
|
||||
endValue = 1f,
|
||||
settings = _tweenSettings
|
||||
};
|
||||
|
||||
_hudSequence = Sequence.Create(useUnscaledTime: true)
|
||||
.Group(Tween.Alpha(_mainCanvasGroup, alphaTween));
|
||||
|
||||
try
|
||||
{
|
||||
await _hudSequence.ToUniTask(cancellationToken: _cancellationTokenSource.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// interrupted by Hide / destroy — safe to ignore
|
||||
}
|
||||
|
||||
_mainCanvasGroup.alpha = 1f;
|
||||
}
|
||||
public async UniTask Hide()
|
||||
{
|
||||
if (_mainCanvasGroup == null)
|
||||
return;
|
||||
|
||||
StopTween();
|
||||
|
||||
_cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
_mainCanvasGroup.blocksRaycasts = false;
|
||||
_mainCanvasGroup.interactable = false;
|
||||
|
||||
var alphaTween = new TweenSettings<float>
|
||||
{
|
||||
startValue = _mainCanvasGroup.alpha,
|
||||
endValue = 0f,
|
||||
settings = _tweenSettings
|
||||
};
|
||||
|
||||
_hudSequence = Sequence.Create(useUnscaledTime: true)
|
||||
.Group(Tween.Alpha(_mainCanvasGroup, alphaTween));
|
||||
|
||||
try
|
||||
{
|
||||
await _hudSequence.ToUniTask(cancellationToken: _cancellationTokenSource.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// interrupted — safe
|
||||
}
|
||||
|
||||
_mainCanvasGroup.alpha = 0f;
|
||||
}
|
||||
|
||||
private void StopTween()
|
||||
{
|
||||
if (_hudSequence.isAlive)
|
||||
_hudSequence.Stop();
|
||||
|
||||
_hudSequence = default;
|
||||
|
||||
if (_cancellationTokenSource != null)
|
||||
{
|
||||
_cancellationTokenSource.Cancel();
|
||||
_cancellationTokenSource.Dispose();
|
||||
_cancellationTokenSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void StopInteractErrorTween()
|
||||
{
|
||||
if (_interactErrorSequence.isAlive)
|
||||
_interactErrorSequence.Stop();
|
||||
|
||||
_interactErrorSequence = default;
|
||||
|
||||
if (_interactCancellationTokenSource != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_interactCancellationTokenSource.Cancel();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
_interactCancellationTokenSource.Dispose();
|
||||
_interactCancellationTokenSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMapClicked()
|
||||
{
|
||||
// Placeholder for later:
|
||||
// - open map window
|
||||
// - toggle map overlay
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user