First commit for private source control. Older commits available on Github.
This commit is contained in:
BIN
Assets/Scripts/Framework/Managers/UI/.DS_Store
vendored
Normal file
BIN
Assets/Scripts/Framework/Managers/UI/.DS_Store
vendored
Normal file
Binary file not shown.
3
Assets/Scripts/Framework/Managers/UI/Base.meta
Normal file
3
Assets/Scripts/Framework/Managers/UI/Base.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdeb86849b3447b08f904cbe2af60572
|
||||
timeCreated: 1773830601
|
||||
15
Assets/Scripts/Framework/Managers/UI/Base/IHud.cs
Normal file
15
Assets/Scripts/Framework/Managers/UI/Base/IHud.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI.Base
|
||||
{
|
||||
public interface IHud
|
||||
{
|
||||
UniTask Hide();
|
||||
UniTask Show();
|
||||
|
||||
UniTask DisplayInteractText(string text);
|
||||
|
||||
GraphicRaycaster Raycaster { get; }
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Framework/Managers/UI/Base/IHud.cs.meta
Normal file
3
Assets/Scripts/Framework/Managers/UI/Base/IHud.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69ce1a09c8ba468184443377cb160251
|
||||
timeCreated: 1773830812
|
||||
15
Assets/Scripts/Framework/Managers/UI/Base/IPopup.cs
Normal file
15
Assets/Scripts/Framework/Managers/UI/Base/IPopup.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI.Base
|
||||
{
|
||||
public interface IPopup
|
||||
{
|
||||
UniTask Show();
|
||||
UniTask Hide();
|
||||
|
||||
UniTask Play(string text, float duration);
|
||||
|
||||
GameObject GameObject { get; }
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Framework/Managers/UI/Base/IPopup.cs.meta
Normal file
3
Assets/Scripts/Framework/Managers/UI/Base/IPopup.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6c40bdc6e55460e859a7d0d76422e5b
|
||||
timeCreated: 1773830634
|
||||
12
Assets/Scripts/Framework/Managers/UI/Base/IScreenFader.cs
Normal file
12
Assets/Scripts/Framework/Managers/UI/Base/IScreenFader.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI.Base
|
||||
{
|
||||
public interface IScreenFader
|
||||
{
|
||||
UniTask FadeFromAsync(float duration);
|
||||
UniTask FadeToAsync(float duration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 486cc0093cdf41db9db9d4a4af124a6f
|
||||
timeCreated: 1773831975
|
||||
12
Assets/Scripts/Framework/Managers/UI/Base/IUIWindow.cs
Normal file
12
Assets/Scripts/Framework/Managers/UI/Base/IUIWindow.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI.Base
|
||||
{
|
||||
public interface IUIWindow
|
||||
{
|
||||
UniTask Show();
|
||||
UniTask Hide();
|
||||
|
||||
WindowType WindowType { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27aca68a2b694025b3ed9c26b2d7d5b2
|
||||
timeCreated: 1769707713
|
||||
9
Assets/Scripts/Framework/Managers/UI/Base/WindowType.cs
Normal file
9
Assets/Scripts/Framework/Managers/UI/Base/WindowType.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace BriarQueen.Framework.Managers.UI.Base
|
||||
{
|
||||
public enum WindowType
|
||||
{
|
||||
PauseMenuWindow,
|
||||
SettingsWindow,
|
||||
CodexWindow
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 616cfa2de3124c308c9706f50b7ab339
|
||||
timeCreated: 1773832262
|
||||
8
Assets/Scripts/Framework/Managers/UI/Events.meta
Normal file
8
Assets/Scripts/Framework/Managers/UI/Events.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75c1e9dba297a499998f45e608b4b71a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Scripts/Framework/Managers/UI/Events/.DS_Store
vendored
Normal file
BIN
Assets/Scripts/Framework/Managers/UI/Events/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
using BriarQueen.Framework.Events.System;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI.Events
|
||||
{
|
||||
public record UIToggleSettingsWindow(bool Show) : IEvent;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf239878f7aa941c2abbef0ebb2e41bd
|
||||
285
Assets/Scripts/Framework/Managers/UI/UICursorService.cs
Normal file
285
Assets/Scripts/Framework/Managers/UI/UICursorService.cs
Normal file
@@ -0,0 +1,285 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI
|
||||
{
|
||||
public sealed class UICursorService : MonoBehaviour
|
||||
{
|
||||
public enum CursorStyle
|
||||
{
|
||||
Default,
|
||||
Interact,
|
||||
Talk,
|
||||
Pickup,
|
||||
Inspect,
|
||||
UseItem,
|
||||
Travel,
|
||||
Knife,
|
||||
}
|
||||
|
||||
[Header("System Cursor")]
|
||||
[SerializeField]
|
||||
private bool _enableCustomCursor = true;
|
||||
|
||||
[SerializeField]
|
||||
private bool _restoreDefaultCursorOnDisable = true;
|
||||
|
||||
[Header("Software Cursor")]
|
||||
[SerializeField]
|
||||
private RectTransform _virtualCursorTransform;
|
||||
|
||||
[SerializeField]
|
||||
private Image _virtualCursorImage;
|
||||
|
||||
[Header("Styles")]
|
||||
[SerializeField]
|
||||
private CursorStyle _startingStyle = CursorStyle.Default;
|
||||
|
||||
[SerializeField]
|
||||
private List<CursorStyleEntry> _styles = new();
|
||||
|
||||
private readonly Dictionary<CursorStyle, CursorStyleEntry> _styleMap = new();
|
||||
|
||||
private EventCoordinator _eventCoordinator;
|
||||
|
||||
private CursorStyle _currentStyle;
|
||||
private CursorStyle _currentStyleOverride = CursorStyle.Default;
|
||||
private bool _isStyleOverridden;
|
||||
|
||||
private Texture2D _currentTexture;
|
||||
private Vector2 _currentHotspot;
|
||||
private CursorMode _currentMode;
|
||||
|
||||
private bool _useVirtualCursor;
|
||||
|
||||
public CursorStyleEntry CurrentStyleEntry => _styleMap[_currentStyle];
|
||||
|
||||
[Inject]
|
||||
private void Construct(EventCoordinator eventCoordinator)
|
||||
{
|
||||
_eventCoordinator = eventCoordinator;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
BuildStyleMap();
|
||||
_currentStyle = _startingStyle;
|
||||
_currentStyleOverride = CursorStyle.Default;
|
||||
_isStyleOverridden = false;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_eventCoordinator?.Subscribe<CursorStyleChangeEvent>(OnCursorStyleChangeEvent);
|
||||
_eventCoordinator?.Subscribe<OverrideCursorStyleChangeEvent>(OnOverrideCursorStyleChangeEvent);
|
||||
|
||||
ApplyCurrentEffectiveStyle();
|
||||
ApplyCursorModeVisuals();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_eventCoordinator?.Unsubscribe<CursorStyleChangeEvent>(OnCursorStyleChangeEvent);
|
||||
_eventCoordinator?.Unsubscribe<OverrideCursorStyleChangeEvent>(OnOverrideCursorStyleChangeEvent);
|
||||
|
||||
if (_restoreDefaultCursorOnDisable)
|
||||
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
BuildStyleMap();
|
||||
}
|
||||
|
||||
public void SetUseVirtualCursor(bool useVirtualCursor)
|
||||
{
|
||||
if (_useVirtualCursor == useVirtualCursor)
|
||||
return;
|
||||
|
||||
_useVirtualCursor = useVirtualCursor;
|
||||
ApplyCursorModeVisuals();
|
||||
ApplyCurrentEffectiveStyle();
|
||||
}
|
||||
|
||||
public void SetVirtualCursorPosition(Vector2 screenPosition)
|
||||
{
|
||||
if (!_useVirtualCursor || _virtualCursorTransform == null)
|
||||
return;
|
||||
|
||||
_virtualCursorTransform.position = screenPosition;
|
||||
}
|
||||
|
||||
public void SetStyle(CursorStyle style)
|
||||
{
|
||||
_currentStyle = style;
|
||||
ApplyCurrentEffectiveStyle();
|
||||
}
|
||||
|
||||
public void SetOverrideStyle(CursorStyle style)
|
||||
{
|
||||
if (style == CursorStyle.Default)
|
||||
{
|
||||
ClearOverrideStyle();
|
||||
return;
|
||||
}
|
||||
|
||||
_isStyleOverridden = true;
|
||||
_currentStyleOverride = style;
|
||||
ApplyCurrentEffectiveStyle();
|
||||
}
|
||||
|
||||
public void ClearOverrideStyle()
|
||||
{
|
||||
_isStyleOverridden = false;
|
||||
_currentStyleOverride = CursorStyle.Default;
|
||||
ApplyCurrentEffectiveStyle();
|
||||
}
|
||||
|
||||
public void ResetToDefault()
|
||||
{
|
||||
_currentStyle = CursorStyle.Default;
|
||||
ClearOverrideStyle();
|
||||
}
|
||||
|
||||
private void OnCursorStyleChangeEvent(CursorStyleChangeEvent evt)
|
||||
{
|
||||
_currentStyle = evt.Style;
|
||||
ApplyCurrentEffectiveStyle();
|
||||
}
|
||||
|
||||
private void OnOverrideCursorStyleChangeEvent(OverrideCursorStyleChangeEvent evt)
|
||||
{
|
||||
if (evt.Style == CursorStyle.Default)
|
||||
{
|
||||
ClearOverrideStyle();
|
||||
return;
|
||||
}
|
||||
|
||||
_isStyleOverridden = true;
|
||||
_currentStyleOverride = evt.Style;
|
||||
ApplyCurrentEffectiveStyle();
|
||||
}
|
||||
|
||||
private void ApplyCursorModeVisuals()
|
||||
{
|
||||
Cursor.visible = !_useVirtualCursor;
|
||||
|
||||
if (_virtualCursorImage != null)
|
||||
_virtualCursorImage.enabled = _useVirtualCursor;
|
||||
}
|
||||
|
||||
private void ApplyCurrentEffectiveStyle()
|
||||
{
|
||||
var style = GetEffectiveStyle();
|
||||
|
||||
if (_useVirtualCursor)
|
||||
{
|
||||
ApplyVirtualCursorStyle(style);
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplySystemCursorStyle(style);
|
||||
}
|
||||
}
|
||||
|
||||
private CursorStyle GetEffectiveStyle()
|
||||
{
|
||||
return _isStyleOverridden ? _currentStyleOverride : _currentStyle;
|
||||
}
|
||||
|
||||
private void ApplyVirtualCursorStyle(CursorStyle style)
|
||||
{
|
||||
if (_virtualCursorImage == null)
|
||||
return;
|
||||
|
||||
if (!_styleMap.TryGetValue(style, out var entry) || entry.Texture == null)
|
||||
{
|
||||
if (!_styleMap.TryGetValue(CursorStyle.Default, out entry) || entry.Texture == null)
|
||||
return;
|
||||
}
|
||||
|
||||
var rect = new Rect(0, 0, entry.Texture.width, entry.Texture.height);
|
||||
var pivot = new Vector2(0.5f, 0.5f);
|
||||
_virtualCursorImage.sprite = Sprite.Create(entry.Texture, rect, pivot);
|
||||
}
|
||||
|
||||
private void ApplySystemCursorStyle(CursorStyle style)
|
||||
{
|
||||
if (!_enableCustomCursor)
|
||||
return;
|
||||
|
||||
if (!_styleMap.TryGetValue(style, out var entry) || entry.Texture == null)
|
||||
{
|
||||
if (_styleMap.TryGetValue(CursorStyle.Default, out var defaultEntry) && defaultEntry.Texture != null)
|
||||
{
|
||||
entry = defaultEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
|
||||
CacheApplied(null, Vector2.zero, CursorMode.Auto);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var hotspot = entry.Hotspot;
|
||||
|
||||
if (entry.Texture != null && entry.HotspotIsNormalized)
|
||||
{
|
||||
hotspot = new Vector2(
|
||||
hotspot.x * entry.Texture.width,
|
||||
hotspot.y * entry.Texture.height);
|
||||
}
|
||||
|
||||
if (IsSameAsCurrent(entry.Texture, hotspot, entry.Mode))
|
||||
return;
|
||||
|
||||
Cursor.SetCursor(entry.Texture, hotspot, entry.Mode);
|
||||
CacheApplied(entry.Texture, hotspot, entry.Mode);
|
||||
}
|
||||
|
||||
private bool IsSameAsCurrent(Texture2D texture, Vector2 hotspot, CursorMode mode)
|
||||
{
|
||||
return _currentTexture == texture &&
|
||||
_currentHotspot == hotspot &&
|
||||
_currentMode == mode;
|
||||
}
|
||||
|
||||
private void CacheApplied(Texture2D texture, Vector2 hotspot, CursorMode mode)
|
||||
{
|
||||
_currentTexture = texture;
|
||||
_currentHotspot = hotspot;
|
||||
_currentMode = mode;
|
||||
}
|
||||
|
||||
private void BuildStyleMap()
|
||||
{
|
||||
_styleMap.Clear();
|
||||
|
||||
if (_styles == null)
|
||||
return;
|
||||
|
||||
for (var i = 0; i < _styles.Count; i++)
|
||||
{
|
||||
var entry = _styles[i];
|
||||
_styleMap[entry.Style] = entry;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct CursorStyleEntry
|
||||
{
|
||||
public CursorStyle Style;
|
||||
public Texture2D Texture;
|
||||
public Vector2 Hotspot;
|
||||
public CursorMode Mode;
|
||||
public bool HotspotIsNormalized;
|
||||
public Vector2 TooltipOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 515a74faf67c4af9912b8b8eed4d8ad7
|
||||
timeCreated: 1769716152
|
||||
434
Assets/Scripts/Framework/Managers/UI/UIManager.cs
Normal file
434
Assets/Scripts/Framework/Managers/UI/UIManager.cs
Normal file
@@ -0,0 +1,434 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
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.Settings;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// UIManager:
|
||||
/// - Modal windows use the window stack
|
||||
/// - Non-modal UI (popups / fader) does not use the stack
|
||||
/// - HUD visibility is event-driven
|
||||
/// - Concrete UI implementations are hidden behind interfaces
|
||||
/// </summary>
|
||||
public class UIManager : IDisposable, IManager
|
||||
{
|
||||
private readonly EventCoordinator _eventCoordinator;
|
||||
private readonly InteractManager _interactManager;
|
||||
private readonly SaveManager _saveManager;
|
||||
private readonly SettingsService _settingsService;
|
||||
|
||||
private readonly Dictionary<WindowType, IUIWindow> _windows = new();
|
||||
private readonly Stack<IUIWindow> _windowStack = new();
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
public bool Initialized { get; private set; }
|
||||
|
||||
private IHud _hudContainer;
|
||||
private IPopup _infoPopup;
|
||||
private IPopup _tutorialPopup;
|
||||
private IScreenFader _screenFader;
|
||||
|
||||
[Inject]
|
||||
public UIManager(
|
||||
EventCoordinator eventCoordinator,
|
||||
InteractManager interactManager,
|
||||
SettingsService settingsService,
|
||||
SaveManager saveManager)
|
||||
{
|
||||
_eventCoordinator = eventCoordinator;
|
||||
_interactManager = interactManager;
|
||||
_settingsService = settingsService;
|
||||
_saveManager = saveManager;
|
||||
}
|
||||
|
||||
private IUIWindow ActiveWindow => _windowStack.Count > 0 ? _windowStack.Peek() : null;
|
||||
|
||||
public bool IsAnyUIOpen => _windowStack.Count > 0;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
if (Initialized)
|
||||
return;
|
||||
|
||||
_disposed = false;
|
||||
SubscribeToEvents();
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!Initialized || _disposed)
|
||||
return;
|
||||
|
||||
_disposed = true;
|
||||
|
||||
UnsubscribeFromEvents();
|
||||
ResetUIStateHard();
|
||||
|
||||
Initialized = false;
|
||||
}
|
||||
|
||||
private void SubscribeToEvents()
|
||||
{
|
||||
_eventCoordinator.Subscribe<PauseButtonClickedEvent>(OnPauseClickReceived);
|
||||
_eventCoordinator.Subscribe<ToggleCodexEvent>(ToggleCodexWindow);
|
||||
_eventCoordinator.Subscribe<UIToggleSettingsWindow>(ToggleSettingsWindow);
|
||||
_eventCoordinator.Subscribe<FadeEvent>(OnFadeEvent);
|
||||
_eventCoordinator.Subscribe<DisplayInteractEvent>(OnDisplayInteractText);
|
||||
_eventCoordinator.Subscribe<DisplayTutorialPopupEvent>(OnTutorialDisplayPopup);
|
||||
_eventCoordinator.Subscribe<CodexChangedEvent>(OnCodexChangedEvent);
|
||||
_eventCoordinator.Subscribe<UIToggleHudEvent>(OnHudToggleEvent);
|
||||
_eventCoordinator.Subscribe<ToolbeltChangedEvent>(OnToolbeltChangedEvent);
|
||||
}
|
||||
|
||||
private void UnsubscribeFromEvents()
|
||||
{
|
||||
_eventCoordinator.Unsubscribe<PauseButtonClickedEvent>(OnPauseClickReceived);
|
||||
_eventCoordinator.Unsubscribe<ToggleCodexEvent>(ToggleCodexWindow);
|
||||
_eventCoordinator.Unsubscribe<UIToggleSettingsWindow>(ToggleSettingsWindow);
|
||||
_eventCoordinator.Unsubscribe<FadeEvent>(OnFadeEvent);
|
||||
_eventCoordinator.Unsubscribe<DisplayInteractEvent>(OnDisplayInteractText);
|
||||
_eventCoordinator.Unsubscribe<DisplayTutorialPopupEvent>(OnTutorialDisplayPopup);
|
||||
_eventCoordinator.Unsubscribe<CodexChangedEvent>(OnCodexChangedEvent);
|
||||
_eventCoordinator.Unsubscribe<UIToggleHudEvent>(OnHudToggleEvent);
|
||||
_eventCoordinator.Unsubscribe<ToolbeltChangedEvent>(OnToolbeltChangedEvent);
|
||||
}
|
||||
|
||||
public void RegisterWindow(IUIWindow window)
|
||||
{
|
||||
if (window == null)
|
||||
return;
|
||||
|
||||
_windows[window.WindowType] = window;
|
||||
window.Hide().Forget();
|
||||
}
|
||||
|
||||
public void RegisterHUD(IHud hudContainer)
|
||||
{
|
||||
_hudContainer = hudContainer;
|
||||
|
||||
if (_hudContainer != null)
|
||||
{
|
||||
_hudContainer.Hide().Forget();
|
||||
_interactManager.AddUIRaycaster(_hudContainer.Raycaster);
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterInfoPopup(IPopup infoPopup)
|
||||
{
|
||||
_infoPopup = infoPopup;
|
||||
|
||||
if (_infoPopup != null)
|
||||
_infoPopup.Hide().Forget();
|
||||
}
|
||||
|
||||
public void RegisterTutorialPopup(IPopup tutorialPopup)
|
||||
{
|
||||
_tutorialPopup = tutorialPopup;
|
||||
|
||||
if (_tutorialPopup != null)
|
||||
_tutorialPopup.Hide().Forget();
|
||||
}
|
||||
|
||||
public void RegisterScreenFader(IScreenFader screenFader)
|
||||
{
|
||||
_screenFader = screenFader;
|
||||
}
|
||||
|
||||
private IUIWindow GetWindow(WindowType windowType)
|
||||
{
|
||||
return _windows.TryGetValue(windowType, out var window) ? window : null;
|
||||
}
|
||||
|
||||
private async UniTask ApplyHudVisibility(bool visible)
|
||||
{
|
||||
if (_disposed || _hudContainer == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
if (visible)
|
||||
await _hudContainer.Show();
|
||||
else
|
||||
await _hudContainer.Hide();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"[UIManager] ApplyHudVisibility error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPauseClickReceived(PauseButtonClickedEvent _)
|
||||
{
|
||||
if (_windowStack.Count > 0)
|
||||
{
|
||||
CloseTopWindow();
|
||||
return;
|
||||
}
|
||||
|
||||
OpenWindow(WindowType.PauseMenuWindow);
|
||||
}
|
||||
|
||||
private void ToggleSettingsWindow(UIToggleSettingsWindow eventData)
|
||||
{
|
||||
if (eventData.Show)
|
||||
OpenWindow(WindowType.SettingsWindow);
|
||||
else
|
||||
CloseWindow(WindowType.SettingsWindow);
|
||||
}
|
||||
|
||||
private void ToggleCodexWindow(ToggleCodexEvent eventData)
|
||||
{
|
||||
if (eventData.Shown)
|
||||
OpenWindow(WindowType.CodexWindow);
|
||||
else
|
||||
CloseWindow(WindowType.CodexWindow);
|
||||
}
|
||||
|
||||
private void OnCodexChangedEvent(CodexChangedEvent eventData)
|
||||
{
|
||||
if (_infoPopup == null)
|
||||
return;
|
||||
|
||||
var duration = _settingsService?.Game?.PopupDisplayDuration ?? 3f;
|
||||
var codexText = GetCodexTextForEntry(eventData.EntryType);
|
||||
|
||||
_infoPopup.Play(codexText, duration).Forget();
|
||||
}
|
||||
|
||||
private void OnToolbeltChangedEvent(ToolbeltChangedEvent eventData)
|
||||
{
|
||||
if (_infoPopup == null)
|
||||
return;
|
||||
|
||||
var duration = _settingsService?.Game?.PopupDisplayDuration ?? 3f;
|
||||
var toolText = GetToolbeltTextForEntry(eventData.ToolID, eventData.Lost);
|
||||
|
||||
_infoPopup.Play(toolText, duration).Forget();
|
||||
}
|
||||
|
||||
private string GetToolbeltTextForEntry(ToolID toolID, bool lost)
|
||||
{
|
||||
if (lost)
|
||||
return $"You lost the {toolID.ToString()}.";
|
||||
else
|
||||
return $"You gained the {toolID.ToString()}.";
|
||||
}
|
||||
|
||||
private string GetCodexTextForEntry(CodexType codexType)
|
||||
{
|
||||
return codexType switch
|
||||
{
|
||||
CodexType.BookEntry => "You've acquired a new book entry.",
|
||||
CodexType.PuzzleClue => "You've acquired a new puzzle clue.",
|
||||
CodexType.Photo => "You've acquired a new photo.",
|
||||
_ => string.Empty
|
||||
};
|
||||
}
|
||||
|
||||
private void OnTutorialDisplayPopup(DisplayTutorialPopupEvent eventData)
|
||||
{
|
||||
if (_tutorialPopup == null)
|
||||
return;
|
||||
|
||||
if (!_settingsService.AreTutorialsEnabled())
|
||||
return;
|
||||
|
||||
var duration = 3f;
|
||||
var tutorialText = TutorialPopupTexts.AllPopups[eventData.TutorialID];
|
||||
|
||||
_tutorialPopup.Play(tutorialText, duration).Forget();
|
||||
}
|
||||
|
||||
private void OnDisplayInteractText(DisplayInteractEvent eventData)
|
||||
{
|
||||
if (_hudContainer == null)
|
||||
return;
|
||||
|
||||
_hudContainer.DisplayInteractText(eventData.Message).Forget();
|
||||
}
|
||||
|
||||
private void OnFadeEvent(FadeEvent eventData)
|
||||
{
|
||||
if (_screenFader == null)
|
||||
return;
|
||||
|
||||
if (eventData.Hidden)
|
||||
_screenFader.FadeFromAsync(eventData.Duration).Forget();
|
||||
else
|
||||
_screenFader.FadeToAsync(eventData.Duration).Forget();
|
||||
}
|
||||
|
||||
private void OnHudToggleEvent(UIToggleHudEvent eventData)
|
||||
{
|
||||
ApplyHudVisibility(eventData.Show).Forget();
|
||||
}
|
||||
|
||||
public void OpenWindow(WindowType windowType)
|
||||
{
|
||||
OpenWindowInternal(windowType).Forget();
|
||||
}
|
||||
|
||||
private async UniTask OpenWindowInternal(WindowType windowType)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
var window = GetWindow(windowType);
|
||||
if (window == null)
|
||||
{
|
||||
Debug.LogError($"[UIManager] Window of type {windowType} not registered.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActiveWindow == window)
|
||||
return;
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Hide();
|
||||
|
||||
_windowStack.Push(window);
|
||||
await window.Show();
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
public void CloseWindow(WindowType windowType)
|
||||
{
|
||||
CloseWindowInternal(windowType).Forget();
|
||||
}
|
||||
|
||||
private async UniTask CloseWindowInternal(WindowType windowType)
|
||||
{
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
|
||||
var target = GetWindow(windowType);
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
while (_windowStack.Count > 0)
|
||||
{
|
||||
var current = _windowStack.Pop();
|
||||
if (current != null)
|
||||
await current.Hide();
|
||||
|
||||
if (current == target)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Show();
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
public void CloseTopWindow()
|
||||
{
|
||||
CloseTopWindowInternal().Forget();
|
||||
}
|
||||
|
||||
private async UniTask CloseTopWindowInternal()
|
||||
{
|
||||
if (_disposed || _windowStack.Count == 0)
|
||||
return;
|
||||
|
||||
var top = _windowStack.Pop();
|
||||
|
||||
if (top != null)
|
||||
await top.Hide();
|
||||
|
||||
if (ActiveWindow != null)
|
||||
await ActiveWindow.Show();
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
public void ResetUIState()
|
||||
{
|
||||
ResetUIStateAsync().Forget();
|
||||
}
|
||||
|
||||
public async UniTask ResetUIStateAsync()
|
||||
{
|
||||
while (_windowStack.Count > 0)
|
||||
{
|
||||
var window = _windowStack.Pop();
|
||||
if (window != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await window.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_tutorialPopup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _tutorialPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (_infoPopup != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _infoPopup.Hide();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
NotifyUIStackChanged();
|
||||
}
|
||||
|
||||
private void ResetUIStateHard()
|
||||
{
|
||||
foreach (var kv in _windows)
|
||||
{
|
||||
if (kv.Value is Component component && component != null)
|
||||
component.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (_tutorialPopup?.GameObject != null)
|
||||
_tutorialPopup.GameObject.SetActive(false);
|
||||
|
||||
if (_infoPopup?.GameObject != null)
|
||||
_infoPopup.GameObject.SetActive(false);
|
||||
|
||||
if (_hudContainer is Component hudComponent && hudComponent != null)
|
||||
hudComponent.gameObject.SetActive(false);
|
||||
|
||||
if (_screenFader is Component faderComponent && faderComponent != null)
|
||||
faderComponent.gameObject.SetActive(false);
|
||||
|
||||
_windowStack.Clear();
|
||||
}
|
||||
|
||||
private void NotifyUIStackChanged()
|
||||
{
|
||||
_eventCoordinator.Publish(new UIStackChangedEvent(_windowStack.Count > 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Framework/Managers/UI/UIManager.cs.meta
Normal file
3
Assets/Scripts/Framework/Managers/UI/UIManager.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 877f1720bf604f91a1b277e25a03dcbe
|
||||
timeCreated: 1769706518
|
||||
Reference in New Issue
Block a user