Files
BABA_YAGA/Assets/Scripts/UI/MainMenuController.cs
2026-04-28 00:07:42 +07:00

147 lines
4.7 KiB
C#

using UnityEngine;
using UnityEngine.UIElements;
using PrimeTween;
using System.Threading.Tasks;
namespace Hallucinate.UI
{
public class MainMenuController : BaseUIController
{
public enum MenuState { Idle, Ribbon }
private MenuState _currentState = MenuState.Idle;
private VisualElement _logo;
private VisualElement _ribbon;
private VisualElement _virtualCursor;
private float _lastInteractionTime;
private const float IDLE_TIMEOUT = 5.0f;
private Tween _pulseTween;
public override void Initialize(VisualElement uxmlRoot, UIManager manager)
{
base.Initialize(uxmlRoot, manager);
_logo = root.Q<VisualElement>("Logo");
_ribbon = root.Q<VisualElement>("Ribbon");
_virtualCursor = root.Q<VisualElement>("VirtualCursor");
if (_logo == null)
{
Debug.LogError($"[MainMenuController] Element 'Logo' not found in UXML! Root children: {root.childCount}");
return;
}
_logo.RegisterCallback<PointerDownEvent>(OnLogoClicked);
// 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();
StartPulse();
_lastInteractionTime = Time.time;
}
public override async Task PlayTransitionIn()
{
await base.PlayTransitionIn();
UnityEngine.Cursor.visible = false;
}
public override async Task PlayTransitionOut()
{
UnityEngine.Cursor.visible = true;
await base.PlayTransitionOut();
}
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);
}
private void OnLogoClicked(PointerDownEvent evt)
{
_lastInteractionTime = Time.time;
if (_currentState == MenuState.Idle)
{
TransitionToRibbon();
}
else
{
_ = uiManager.Push<LobbyController>();
}
}
private void TransitionToRibbon()
{
_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);
_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);
}
private void TransitionToIdle()
{
_currentState = MenuState.Idle;
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);
}
public void Update()
{
UpdateVirtualCursor();
if (_currentState == MenuState.Ribbon)
{
if (Time.time - _lastInteractionTime > IDLE_TIMEOUT)
{
TransitionToIdle();
}
}
}
private void UpdateVirtualCursor()
{
if (_virtualCursor == null) return;
Vector2 mousePos = Input.mousePosition;
float x = mousePos.x;
float y = Screen.height - mousePos.y;
if (_currentState == MenuState.Ribbon)
{
y = Screen.height / 2f + 50;
}
_virtualCursor.style.left = x - _virtualCursor.layout.width / 2;
_virtualCursor.style.top = y - _virtualCursor.layout.height / 2;
}
}
}