Files
PGiZ2/Assets/Code/UI/MainMenuController.cs
T
2026-02-07 13:34:37 +03:00

160 lines
5.1 KiB
C#

using Code.DI;
using Code.Input;
using DG.Tweening;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace Code.UI
{
public class MainMenuController : MonoBehaviour
{
[SerializeField] private TMP_Text logotype;
[SerializeField] private Button startGameButton;
[SerializeField] private Button exitButton;
[SerializeField] private Transform parallaxRoot;
[SerializeField] private Image fader;
[SerializeField] private Image backgroundImage;
[SerializeField] private float parallaxStrength = 15f;
[SerializeField] private float parallaxSmoothTime = 0.1f;
private Vector3 _targetParallaxOffset;
private Vector3 _currentParallaxOffset;
private IInputService _inputService;
private AudioSource _audioSource;
private void Start()
{
var container = FindFirstObjectByType<DIContainer>();
_inputService = container.Resolve<IInputService>();
_inputService.EnableMap(ActionMapping.MainMenu);
_audioSource = FindFirstObjectByType<AudioSource>();
SetupButtons();
AnimateLogo();
AnimateBackground();
FadeIn();
}
private void SetupButtons()
{
startGameButton.onClick.AddListener(OnStartGameClicked);
exitButton.onClick.AddListener(OnExitButtonClicked);
}
private void AnimateLogo()
{
var rect = logotype.rectTransform;
var originalColor = logotype.color;
rect.localScale = Vector3.zero;
rect.rotation = Quaternion.Euler(0, 0, -20f);
logotype.color = new Color(originalColor.r, originalColor.g, originalColor.b, 0f);
var logoSequence = DOTween.Sequence();
logoSequence.Append(rect.DOScale(Vector3.one * 1.2f, 0.6f).SetEase(Ease.OutBack))
.Join(rect.DORotate(Vector3.zero, 0.6f).SetEase(Ease.OutSine))
.Join(logotype.DOColor(originalColor, 0.6f));
logoSequence.OnComplete(() =>
{
rect.DOScale(new Vector3(1.08f, 1.08f, 1f), 5f)
.SetLoops(-1, LoopType.Yoyo)
.SetEase(Ease.InOutSine);
logotype.DOColor(new Color(originalColor.r, originalColor.g, originalColor.b, 0.6f), 3f)
.SetLoops(-1, LoopType.Yoyo)
.SetEase(Ease.InOutSine);
});
}
private void AnimateBackground()
{
if (backgroundImage == null) return;
var rect = backgroundImage.rectTransform;
rect.DOScale(1.2f, 25f)
.SetLoops(-1, LoopType.Yoyo)
.SetEase(Ease.InOutSine);
}
private void FadeIn()
{
_audioSource.volume = 0f;
_audioSource.DOFade(1f, 1f).SetEase(Ease.Linear);
fader.color = new Color(0, 0, 0, 1f);
fader.DOFade(0f, 1f).SetEase(Ease.Linear);
fader.raycastTarget = false;
}
private void Update()
{
HandleParallax();
}
private void HandleParallax()
{
if (!parallaxRoot) return;
var mousePos = _inputService.MainMenuParalax;
var center = new Vector2(Screen.width / 2f, Screen.height / 2f);
if (center.x == 0 || center.y == 0) return;
var offset = (mousePos - center) / center;
_targetParallaxOffset = new Vector3(
-offset.x * parallaxStrength,
-offset.y * parallaxStrength,
0f
);
_currentParallaxOffset = Vector3.Lerp(
_currentParallaxOffset,
_targetParallaxOffset,
Time.deltaTime / parallaxSmoothTime
);
parallaxRoot.localPosition = _currentParallaxOffset;
}
private void OnStartGameClicked() => FadeOutAndLoad("Gameplay1");
private void OnExitButtonClicked() => FadeOutAndQuit();
private void FadeOutAndLoad(string sceneName)
{
fader.raycastTarget = true;
_audioSource.DOFade(0, 0.8f).SetEase(Ease.Linear);
fader.DOFade(1f, 0.8f).OnComplete(() =>
{
SceneManager.LoadScene(sceneName);
});
}
private void FadeOutAndQuit()
{
fader.raycastTarget = true;
_audioSource.DOFade(0, 0.8f).SetEase(Ease.Linear);
fader.DOFade(1f, 0.8f).OnComplete(() =>
{
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
});
}
private void OnDestroy()
{
_inputService?.DisableMap(ActionMapping.MainMenu);
_inputService?.DisableMap(ActionMapping.Gameplay);
startGameButton?.onClick.RemoveListener(OnStartGameClicked);
exitButton?.onClick.RemoveListener(OnExitButtonClicked);
}
}
}