Files
BABA_YAGA/Assets/Scripts/UI/MainMenuController.cs

147 lines
4.7 KiB
C#
Raw Normal View History

2026-04-25 18:20:16 +07:00
using UnityEngine;
using UnityEngine.UIElements;
2026-04-28 00:07:42 +07:00
using PrimeTween;
using System.Threading.Tasks;
2026-04-25 18:20:16 +07:00
2026-04-28 00:07:42 +07:00
namespace Hallucinate.UI
2026-04-25 18:20:16 +07:00
{
2026-04-28 00:07:42 +07:00
public class MainMenuController : BaseUIController
2026-04-25 18:20:16 +07:00
{
2026-04-28 00:07:42 +07:00
public enum MenuState { Idle, Ribbon }
private MenuState _currentState = MenuState.Idle;
2026-04-26 04:39:59 +07:00
private VisualElement _logo;
private VisualElement _ribbon;
2026-04-28 00:07:42 +07:00
private VisualElement _virtualCursor;
2026-04-26 05:20:47 +07:00
private float _lastInteractionTime;
2026-04-28 00:07:42 +07:00
private const float IDLE_TIMEOUT = 5.0f;
2026-04-25 18:20:16 +07:00
2026-04-28 00:07:42 +07:00
private Tween _pulseTween;
2026-04-26 04:39:59 +07:00
2026-04-28 00:07:42 +07:00
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
{
base.Initialize(uxmlRoot, manager);
2026-04-26 04:39:59 +07:00
2026-04-28 00:07:42 +07:00
_logo = root.Q<VisualElement>("Logo");
_ribbon = root.Q<VisualElement>("Ribbon");
_virtualCursor = root.Q<VisualElement>("VirtualCursor");
2026-04-25 18:20:16 +07:00
2026-04-28 00:07:42 +07:00
if (_logo == null)
2026-04-27 15:48:17 +07:00
{
2026-04-28 00:07:42 +07:00
Debug.LogError($"[MainMenuController] Element 'Logo' not found in UXML! Root children: {root.childCount}");
return;
2026-04-27 15:48:17 +07:00
}
2026-04-28 00:07:42 +07:00
_logo.RegisterCallback<PointerDownEvent>(OnLogoClicked);
2026-04-26 05:20:47 +07:00
2026-04-28 00:07:42 +07:00
// Bind Buttons with null checks
var settingsBtn = root.Q<Button>("SettingsBtn");
if (settingsBtn != null) settingsBtn.clicked += () => uiManager.Push<SettingsController>();
var joinBtn = root.Q<Button>("JoinBtn");
if (joinBtn != null) joinBtn.clicked += () => uiManager.Push<LobbyController>();
var createBtn = root.Q<Button>("CreateBtn");
if (createBtn != null) createBtn.clicked += () => uiManager.Push<LobbyController>();
var profileBtn = root.Q<Button>("ProfileBtn");
if (profileBtn != null) profileBtn.clicked += () => uiManager.Push<ProfileController>();
var exitBtn = root.Q<Button>("ExitBtn");
if (exitBtn != null) exitBtn.clicked += () => Application.Quit();
2026-04-26 05:20:47 +07:00
2026-04-28 00:07:42 +07:00
StartPulse();
_lastInteractionTime = Time.time;
2026-04-26 05:20:47 +07:00
}
2026-04-28 00:07:42 +07:00
public override async Task PlayTransitionIn()
2026-04-26 05:20:47 +07:00
{
2026-04-28 00:07:42 +07:00
await base.PlayTransitionIn();
UnityEngine.Cursor.visible = false;
2026-04-26 05:20:47 +07:00
}
2026-04-28 00:07:42 +07:00
public override async Task PlayTransitionOut()
2026-04-26 04:39:59 +07:00
{
2026-04-28 00:07:42 +07:00
UnityEngine.Cursor.visible = true;
await base.PlayTransitionOut();
}
2026-04-27 13:27:40 +07:00
2026-04-28 00:07:42 +07:00
private void StartPulse()
{
// Use Vector3.one * 1.1f for target scale
_pulseTween = Tween.Scale(_logo.transform, Vector3.one * 1.1f, duration: 0.8f, cycles: -1, cycleMode: CycleMode.Yoyo, ease: Ease.InOutSine);
2026-04-27 15:48:17 +07:00
}
2026-04-28 00:07:42 +07:00
private void OnLogoClicked(PointerDownEvent evt)
2026-04-27 15:48:17 +07:00
{
2026-04-28 00:07:42 +07:00
_lastInteractionTime = Time.time;
if (_currentState == MenuState.Idle)
2026-04-27 15:48:17 +07:00
{
2026-04-28 00:07:42 +07:00
TransitionToRibbon();
2026-04-27 15:48:17 +07:00
}
else
{
2026-04-28 00:07:42 +07:00
_ = uiManager.Push<LobbyController>();
2026-04-26 05:02:49 +07:00
}
2026-04-26 04:39:59 +07:00
}
2026-04-28 00:07:42 +07:00
private void TransitionToRibbon()
2026-04-26 05:20:47 +07:00
{
2026-04-28 00:07:42 +07:00
_currentState = MenuState.Ribbon;
// Transition Logo using Custom tween for offset
Tween.Custom(0f, -300f, duration: 0.5f, ease: Ease.OutQuad,
onValueChange: val => _logo.style.left = val);
2026-04-26 05:20:47 +07:00
2026-04-28 00:07:42 +07:00
_ribbon.style.display = DisplayStyle.Flex;
_ribbon.style.opacity = 0;
// Fade in Ribbon
Tween.Custom(0f, 1f, duration: 0.5f, onValueChange: val => _ribbon.style.opacity = val);
2026-04-27 13:27:40 +07:00
}
2026-04-28 00:07:42 +07:00
private void TransitionToIdle()
2026-04-26 05:20:47 +07:00
{
2026-04-28 00:07:42 +07:00
_currentState = MenuState.Idle;
2026-04-27 13:27:40 +07:00
2026-04-28 00:07:42 +07:00
Tween.Custom(-300f, 0f, duration: 0.5f, ease: Ease.OutQuad,
onValueChange: val => _logo.style.left = val);
Tween.Custom(1f, 0f, duration: 0.5f, onValueChange: val => _ribbon.style.opacity = val)
.OnComplete(() => _ribbon.style.display = DisplayStyle.None);
2026-04-26 05:20:47 +07:00
}
2026-04-28 00:07:42 +07:00
public void Update()
2026-04-26 04:39:59 +07:00
{
2026-04-28 00:07:42 +07:00
UpdateVirtualCursor();
2026-04-26 05:20:47 +07:00
2026-04-28 00:07:42 +07:00
if (_currentState == MenuState.Ribbon)
{
if (Time.time - _lastInteractionTime > IDLE_TIMEOUT)
{
TransitionToIdle();
}
}
2026-04-26 04:39:59 +07:00
}
2026-04-26 05:20:47 +07:00
2026-04-28 00:07:42 +07:00
private void UpdateVirtualCursor()
2026-04-26 05:20:47 +07:00
{
2026-04-28 00:07:42 +07:00
if (_virtualCursor == null) return;
2026-04-27 13:27:40 +07:00
2026-04-28 00:07:42 +07:00
Vector2 mousePos = Input.mousePosition;
float x = mousePos.x;
float y = Screen.height - mousePos.y;
2026-04-26 05:20:47 +07:00
2026-04-28 00:07:42 +07:00
if (_currentState == MenuState.Ribbon)
{
y = Screen.height / 2f + 50;
}
2026-04-26 05:20:47 +07:00
2026-04-28 00:07:42 +07:00
_virtualCursor.style.left = x - _virtualCursor.layout.width / 2;
_virtualCursor.style.top = y - _virtualCursor.layout.height / 2;
2026-04-26 05:20:47 +07:00
}
2026-04-25 18:20:16 +07:00
}
}