Update HUD updates, moving scattered prefabs into a central HUD manager (#53)
Co-authored-by: Michal Pikulski <michal.a.pikulski@gmail.com> Reviewed-on: #53
This commit is contained in:
@@ -1,89 +1,122 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using SkiaSharp.Unity;
|
||||
using Input;
|
||||
using AppleHills.Core;
|
||||
using UI.Core;
|
||||
using Pixelplacement;
|
||||
using Pixelplacement.TweenSystem;
|
||||
using UI;
|
||||
using UnityEngine.Events;
|
||||
|
||||
public class AppSwitcher : MonoBehaviour
|
||||
public class AppSwitcher : UIPage
|
||||
{
|
||||
|
||||
public TextAsset iconIdle;
|
||||
public TextAsset iconEstablish;
|
||||
public TextAsset rainbowEstablish;
|
||||
public TextAsset rainbowRemove;
|
||||
public GameObject rainbow;
|
||||
public GameObject icon;
|
||||
public GameObject rainbowIn;
|
||||
public GameObject rainbowOut;
|
||||
public GameObject gameLayoutContainer;
|
||||
public GameObject exitButton;
|
||||
public RectMask2D rectMask;
|
||||
|
||||
[Header("Slide Animation Settings")]
|
||||
public float slideDuration = 0.5f;
|
||||
|
||||
private SkottiePlayerV2 rainbowInPlayer;
|
||||
private SkottiePlayerV2 rainbowOutPlayer;
|
||||
private TweenBase slideInTween;
|
||||
private TweenBase slideOutTween;
|
||||
|
||||
private SkottiePlayerV2 iconPlayer;
|
||||
private SkottiePlayerV2 rainbowPlayer;
|
||||
private Animator animator;
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
protected override void OnManagedAwake()
|
||||
{
|
||||
iconPlayer = icon.GetComponentInChildren<SkottiePlayerV2>();
|
||||
rainbowPlayer = rainbow.GetComponentInChildren<SkottiePlayerV2>();
|
||||
animator = GetComponent<Animator>();
|
||||
rainbow.SetActive(false);
|
||||
base.OnManagedAwake();
|
||||
|
||||
PageName = "AppSwitcher";
|
||||
rainbowInPlayer = rainbowIn.GetComponent<SkottiePlayerV2>();
|
||||
rainbowOutPlayer = rainbowOut.GetComponent<SkottiePlayerV2>();
|
||||
|
||||
if (rectMask == null)
|
||||
{
|
||||
rectMask = GetComponent<RectMask2D>();
|
||||
}
|
||||
|
||||
// Initially hide both
|
||||
rainbowIn.SetActive(true);
|
||||
exitButton.SetActive(false);
|
||||
}
|
||||
|
||||
public void OpenAppSwitcher()
|
||||
protected override void DoTransitionIn(Action onComplete)
|
||||
{
|
||||
PlayerHudManager.Instance.HideAllHudExcept(gameObject);
|
||||
|
||||
rainbow.SetActive(true);
|
||||
//Activate players
|
||||
rainbow.SetActive(true);
|
||||
gameLayoutContainer.SetActive(true);
|
||||
|
||||
// Play establishing animations
|
||||
rainbowPlayer.LoadAnimation(rainbowEstablish.text);
|
||||
rainbowPlayer.PlayAnimation(false);
|
||||
rainbowPlayer.loop = false;
|
||||
gameLayoutContainer.SetActive(true);
|
||||
animator.Play("GamesReveal");
|
||||
|
||||
// Show the exit button
|
||||
exitButton.SetActive(true);
|
||||
|
||||
// Set input mode to UI
|
||||
QuickAccess.Instance.PlayerController.InterruptMoveTo();
|
||||
InputManager.Instance.SetInputMode(InputMode.UI);
|
||||
|
||||
gameLayoutContainer.SetActive(true);
|
||||
|
||||
rainbowPlayer.OnAnimationFinished += AnimFinished;
|
||||
// Hide rainbow out, show rainbow in
|
||||
rainbowOut.SetActive(false);
|
||||
|
||||
// Play animation on rainbow in without resetting state
|
||||
rainbowInPlayer.PlayAnimation(true);
|
||||
|
||||
// Slide in animation - tween padding.left from 1700 to 0
|
||||
slideInTween = TweenPaddingLeft(1700f, 0f, Tween.EaseOut, () =>
|
||||
{
|
||||
onComplete?.Invoke();
|
||||
rainbowOut.SetActive(true);
|
||||
exitButton.SetActive(true);
|
||||
});
|
||||
}
|
||||
|
||||
public void CloseAppSwitcher()
|
||||
protected override void DoTransitionOut(Action onComplete)
|
||||
{
|
||||
rainbowPlayer.resetAfterFinished = true;
|
||||
rainbowPlayer.LoadAnimation(rainbowRemove.text);
|
||||
rainbowPlayer.PlayAnimation(false);
|
||||
rainbowPlayer.loop = false;
|
||||
animator.Play("GamesHide");
|
||||
|
||||
// Set input mode to game and ui
|
||||
InputManager.Instance.SetInputMode(InputMode.GameAndUI);
|
||||
rainbowIn.SetActive(false);
|
||||
|
||||
// Play animation on rainbow out with resetting state
|
||||
rainbowOutPlayer.PlayAnimation(true);
|
||||
|
||||
// Hide the exit button
|
||||
exitButton.SetActive(false);
|
||||
|
||||
PlayerHudManager.Instance.ShowAllHud();
|
||||
// Slide out animation - tween padding.left from 0 to 1700
|
||||
slideOutTween = TweenPaddingLeft(0f, 1700f, Tween.EaseIn, () => {
|
||||
gameLayoutContainer.SetActive(false);
|
||||
rainbowIn.SetActive(true);
|
||||
onComplete?.Invoke();
|
||||
InputManager.Instance.SetInputMode(InputMode.GameAndUI);
|
||||
});
|
||||
}
|
||||
|
||||
public void GamesHiddenAnimationEvent()
|
||||
{
|
||||
rainbow.SetActive(false);
|
||||
gameLayoutContainer.SetActive(false);
|
||||
|
||||
}
|
||||
|
||||
private void AnimFinished(string str)
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Tweens the left padding of the rectMask from startValue to endValue.
|
||||
/// </summary>
|
||||
private TweenBase TweenPaddingLeft(float startValue, float endValue, AnimationCurve easeCurve, Action onComplete)
|
||||
{
|
||||
// Set starting position
|
||||
Vector4 startPadding = rectMask.padding;
|
||||
startPadding.x = startValue;
|
||||
rectMask.padding = startPadding;
|
||||
|
||||
return Tween.Value(
|
||||
startValue,
|
||||
endValue,
|
||||
(value) => {
|
||||
Vector4 padding = rectMask.padding;
|
||||
padding.x = value;
|
||||
rectMask.padding = padding;
|
||||
},
|
||||
slideDuration,
|
||||
0f, // no delay
|
||||
easeCurve,
|
||||
Tween.LoopType.None,
|
||||
null, // onStart
|
||||
onComplete
|
||||
);
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
// Clean up tweens
|
||||
slideInTween?.Stop();
|
||||
slideOutTween?.Stop();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -165,15 +165,6 @@ namespace UI.CardSystem
|
||||
UIPageController.Instance.PopPage();
|
||||
}
|
||||
}
|
||||
// If album exits while in Overworld, show AppSwitcher. If not, keep it hidden.
|
||||
if (PlayerHudManager.Instance.currentUIMode == PlayerHudManager.UIMode.Overworld)
|
||||
{
|
||||
PlayerHudManager.Instance.ToggleAppSwitcher(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerHudManager.Instance.ToggleAppSwitcher(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBoosterCountChanged(int newCount)
|
||||
|
||||
@@ -70,11 +70,8 @@ namespace UI.CardSystem
|
||||
if (albumViewPage != null)
|
||||
{
|
||||
UIPageController.Instance.PushPage(albumViewPage);
|
||||
PlayerHudManager.Instance.appSwitcher.SetActive(false);
|
||||
}
|
||||
}
|
||||
PlayerHudManager.Instance.ToggleAppSwitcher(false);
|
||||
// If we're already on the album main page, do nothing
|
||||
}
|
||||
|
||||
private void OnPageChanged(UIPage currentPage)
|
||||
|
||||
@@ -190,23 +190,35 @@ namespace UI.Core
|
||||
{
|
||||
if (_pageStack.Count <= 0) return;
|
||||
|
||||
// Hide and pop current page
|
||||
// Pop current page from stack
|
||||
UIPage currentPage = _pageStack.Pop();
|
||||
currentPage.TransitionOut();
|
||||
|
||||
// Show previous page if there is one
|
||||
if (_pageStack.Count > 0)
|
||||
// Subscribe to transition out completion event
|
||||
Action onTransitionComplete = null;
|
||||
onTransitionComplete = () =>
|
||||
{
|
||||
UIPage previousPage = _pageStack.Peek();
|
||||
previousPage.TransitionIn();
|
||||
OnPageChanged?.Invoke(previousPage);
|
||||
Logging.Debug($"[UIPageController] Popped to previous page: {previousPage.PageName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
OnPageChanged?.Invoke(null);
|
||||
Logging.Debug("[UIPageController] Popped last page, no pages left in stack");
|
||||
}
|
||||
// Unsubscribe to prevent memory leaks
|
||||
currentPage.OnTransitionOutCompleted -= onTransitionComplete;
|
||||
|
||||
// Fire OnPageChanged AFTER transition completes
|
||||
if (_pageStack.Count > 0)
|
||||
{
|
||||
UIPage previousPage = _pageStack.Peek();
|
||||
previousPage.TransitionIn();
|
||||
OnPageChanged?.Invoke(previousPage);
|
||||
Logging.Debug($"[UIPageController] Popped to previous page: {previousPage.PageName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
OnPageChanged?.Invoke(null);
|
||||
Logging.Debug("[UIPageController] Popped last page, no pages left in stack");
|
||||
}
|
||||
};
|
||||
|
||||
currentPage.OnTransitionOutCompleted += onTransitionComplete;
|
||||
|
||||
// Start the transition out animation
|
||||
currentPage.TransitionOut();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -31,9 +31,8 @@ namespace UI
|
||||
public GameObject CinematicBackground;
|
||||
|
||||
[Header("HUD Elements")]
|
||||
public GameObject appSwitcher;
|
||||
public GameObject eagleEye;
|
||||
|
||||
public GameObject ramaSjangButton;
|
||||
|
||||
[HideInInspector] public Image cinematicSprites;
|
||||
[HideInInspector] public Image cinematicBackgroundSprites;
|
||||
@@ -64,12 +63,6 @@ namespace UI
|
||||
UnityEngine.Debug.LogError("[PlayerHudManager] UIPageController not found on same GameObject!");
|
||||
}
|
||||
|
||||
// Get AppSwitcher component reference
|
||||
if (appSwitcher != null)
|
||||
{
|
||||
_appSwitcherComponent = appSwitcher.GetComponent<AppSwitcher>();
|
||||
}
|
||||
|
||||
InitializeReferences();
|
||||
}
|
||||
|
||||
@@ -164,53 +157,17 @@ namespace UI
|
||||
switch (sceneName)
|
||||
{
|
||||
case "AppleHillsOverworld":
|
||||
UpdateUIMode(UIMode.Overworld);
|
||||
currentUIMode = UIMode.Overworld;
|
||||
break;
|
||||
case "Quarry":
|
||||
UpdateUIMode(UIMode.Puzzle);
|
||||
currentUIMode = UIMode.Puzzle;
|
||||
break;
|
||||
case "DivingForPictures":
|
||||
UpdateUIMode(UIMode.Minigame);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void UpdateUIMode(UIMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case UIMode.Overworld:
|
||||
// Update currentUIMode var
|
||||
currentUIMode = UIMode.Overworld;
|
||||
// Show app switcher
|
||||
appSwitcher.SetActive(true);
|
||||
// Hide eagle eye
|
||||
eagleEye.SetActive(false);
|
||||
break;
|
||||
case UIMode.Puzzle:
|
||||
// Update currentUIMode var
|
||||
currentUIMode = UIMode.Puzzle;
|
||||
// Hide app switcher
|
||||
appSwitcher.SetActive(false);
|
||||
// show eagle eye
|
||||
eagleEye.SetActive(true);
|
||||
break;
|
||||
case UIMode.Minigame:
|
||||
// Update currentUIMode var
|
||||
currentUIMode = UIMode.Minigame;
|
||||
// Hide app switcher
|
||||
appSwitcher.SetActive(false);
|
||||
// Hide birds eye
|
||||
eagleEye.SetActive(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleAppSwitcher(bool boo)
|
||||
{
|
||||
appSwitcher.SetActive(boo);
|
||||
|
||||
ShowAllHud();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -263,14 +220,47 @@ namespace UI
|
||||
return;
|
||||
}
|
||||
|
||||
// Set visibility for all HUD children
|
||||
foreach (Transform child in hudButtonsContainer)
|
||||
{
|
||||
child.gameObject.SetActive(visible);
|
||||
}
|
||||
|
||||
ApplyUIModeOverrides(visible);
|
||||
|
||||
Logging.Debug($"[PlayerHudManager] {(visible ? "Shown" : "Hidden")} all HUD elements");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies UI mode-specific visibility rules (e.g., hiding eagleEye in certain modes)
|
||||
/// </summary>
|
||||
private void ApplyUIModeOverrides(bool visible)
|
||||
{
|
||||
switch (currentUIMode)
|
||||
{
|
||||
case UIMode.Overworld:
|
||||
if (visible)
|
||||
{
|
||||
eagleEye.SetActive(false);
|
||||
}
|
||||
break;
|
||||
case UIMode.Puzzle:
|
||||
if (visible)
|
||||
{
|
||||
ramaSjangButton.SetActive(false);
|
||||
}
|
||||
break;
|
||||
case UIMode.Minigame:
|
||||
if (visible)
|
||||
{
|
||||
eagleEye.SetActive(false);
|
||||
}
|
||||
break;
|
||||
case UIMode.HideAll:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Automatically manages HUD visibility based on page stack state
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user