123 lines
3.6 KiB
C#
123 lines
3.6 KiB
C#
using Cysharp.Threading.Tasks;
|
||
using DG.Tweening;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Threading;
|
||
using UnityEngine;
|
||
|
||
public class MenuLayoutController : MonoBehaviour, IControlable
|
||
{
|
||
public event Action OnTransitionFinished;
|
||
|
||
[Header("Панели")]
|
||
[SerializeField] List<MenuPanel> _panels;
|
||
int _panelIndex = 0;
|
||
|
||
[Header("Анимация открытия/закрытия")]
|
||
[SerializeField] private RectTransform _leftPanel;
|
||
[SerializeField] private RectTransform _rightPanel;
|
||
[SerializeField] private float _transitionSpeed;
|
||
[SerializeField] private Ease _ease;
|
||
private float _leftOpenedPosition;
|
||
private float _rightOpenedPosition;
|
||
private Sequence _sequence;
|
||
|
||
public bool ControlsEnabled { get; set; }
|
||
|
||
public void Initialize()
|
||
{
|
||
foreach (var panel in _panels)
|
||
{
|
||
panel.Initialize();
|
||
panel.Disable(0);
|
||
}
|
||
|
||
_panels[_panelIndex].Enable(0, 0);
|
||
ControlsEnabled = true;
|
||
|
||
_leftOpenedPosition = _leftPanel.anchoredPosition.x;
|
||
_rightOpenedPosition = _rightPanel.anchoredPosition.x;
|
||
}
|
||
|
||
public void UpdateControls()
|
||
{
|
||
int direction = GetDirection();
|
||
|
||
int newPanelIndex = Mathf.Clamp(_panelIndex + direction, 0, 2);
|
||
bool indexChanged = newPanelIndex != _panelIndex;
|
||
var currentPanel = _panels[_panelIndex];
|
||
|
||
if (indexChanged)
|
||
{
|
||
var nextPanel = _panels[newPanelIndex];
|
||
currentPanel.Disable(0);
|
||
nextPanel.Enable(0, 0);
|
||
|
||
_panelIndex = newPanelIndex;
|
||
}
|
||
|
||
if (In.GetButtonDownAnyPlayer(PlayerAction.action))
|
||
currentPanel.Interact();
|
||
}
|
||
|
||
private static int GetDirection()
|
||
{
|
||
int dir_h = 0;
|
||
dir_h += In.GetButtonDownAnyPlayer(PlayerAction.right) ? 1 : 0;
|
||
dir_h += In.GetButtonDownAnyPlayer(PlayerAction.left) ? -1 : 0;
|
||
return dir_h;
|
||
}
|
||
|
||
public void Open() => SetMenuState(true);
|
||
public void Close() => SetMenuState(false);
|
||
|
||
private void SetMenuState(bool open)
|
||
{
|
||
float leftTarget = open ? _leftOpenedPosition : 0;
|
||
float rightTarget = open ? _rightOpenedPosition : 0;
|
||
PerformTransition(leftTarget, rightTarget);
|
||
}
|
||
|
||
private void PerformTransition(float targetLeftX, float targetRightX)
|
||
{
|
||
if (_leftPanel == null || _rightPanel == null)
|
||
{
|
||
Debug.LogError("Панели не назначены!");
|
||
return;
|
||
}
|
||
|
||
if (_sequence != null)
|
||
{
|
||
_sequence.Kill(complete: false);
|
||
_sequence = null;
|
||
}
|
||
|
||
OnTransitionFinished = null;
|
||
|
||
float distanceLeft = Mathf.Abs(targetLeftX - _leftPanel.anchoredPosition.x);
|
||
float distanceRight = Mathf.Abs(targetRightX - _rightPanel.anchoredPosition.x);
|
||
|
||
float durationLeft = distanceLeft / _transitionSpeed;
|
||
float durationRight = distanceRight / _transitionSpeed;
|
||
float duration = Mathf.Max(durationLeft, durationRight); // Чтобы обе закончили вместе
|
||
|
||
_sequence = DOTween.Sequence();
|
||
|
||
Tween left = _leftPanel.DOAnchorPosX(targetLeftX, duration)
|
||
.SetEase(_ease);
|
||
|
||
Tween right = _rightPanel.DOAnchorPosX(targetRightX, duration)
|
||
.SetEase(_ease);
|
||
|
||
_sequence.Join(left);
|
||
_sequence.Join(right);
|
||
|
||
_sequence.OnComplete(() =>
|
||
{
|
||
OnTransitionFinished?.Invoke();
|
||
_sequence = null;
|
||
});
|
||
|
||
_sequence.PlayForward();
|
||
}
|
||
} |