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 = 25f; [SerializeField] private float parallaxSharpness = 15f; [SerializeField] private float logoAppearDuration = 0.3f; [SerializeField] private float logoPunchScale = 1.2f; [SerializeField] private float logoPunchDuration = 0.2f; [SerializeField] private float backgroundZoomSpeed = 15f; private Vector3 _targetParallaxOffset; private Vector3 _currentParallaxOffset; private IInputService _inputService; private AudioSource _audioSource; private void Start() { var container = FindFirstObjectByType(); _inputService = container.Resolve(); _inputService.EnableMap(ActionMapping.MainMenu); _audioSource = FindFirstObjectByType(); SetupButtons(); AnimateLogo(); AnimateBackground(); FadeIn(); } private void SetupButtons() { startGameButton.onClick.AddListener(OnStartGameClicked); exitButton.onClick.AddListener(OnExitButtonClicked); AddButtonHoverEffect(startGameButton); AddButtonHoverEffect(exitButton); } private void AddButtonHoverEffect(Button button) { var rect = button.GetComponent(); button.onClick.AddListener(() => { rect.DOPunchScale(Vector3.one * 0.2f, 0.1f, 5, 0.5f); }); } private void AnimateLogo() { var rect = logotype.rectTransform; var originalColor = logotype.color; rect.localScale = Vector3.zero; logotype.color = new Color(originalColor.r, originalColor.g, originalColor.b, 0f); var logoSequence = DOTween.Sequence(); logoSequence.Append(rect.DOScale(logoPunchScale, logoAppearDuration).SetEase(Ease.OutQuint)) .Join(logotype.DOColor(originalColor, logoAppearDuration).SetEase(Ease.OutQuint)) .Append(rect.DOScale(1f, 0.1f).SetEase(Ease.InOutSine)); logoSequence.OnComplete(() => { rect.DOPunchScale(Vector3.one * 0.1f, 0.3f, 3, 0.5f) .SetLoops(-1, LoopType.Restart) .SetEase(Ease.InOutSine); logotype.DOColor(new Color(originalColor.r, originalColor.g, originalColor.b, 0.8f), 0.2f) .SetLoops(-1, LoopType.Yoyo) .SetEase(Ease.InOutSine); }); } private void AnimateBackground() { if (backgroundImage == null) return; var rect = backgroundImage.rectTransform; rect.DOScale(1.3f, backgroundZoomSpeed) .SetEase(Ease.InOutQuad) .SetLoops(-1, LoopType.Yoyo); rect.DORotate(new Vector3(0, 0, 2f), 10f) .SetEase(Ease.InOutSine) .SetLoops(-1, LoopType.Yoyo); } private void FadeIn() { _audioSource.volume = 0f; _audioSource.DOFade(1f, 0.5f).SetEase(Ease.OutQuint); fader.color = new Color(0, 0, 0, 1f); fader.DOFade(0f, 0.5f).SetEase(Ease.OutQuint); 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 * parallaxSharpness ); parallaxRoot.localPosition = _currentParallaxOffset; } private void OnStartGameClicked() { startGameButton.transform.DOPunchScale(Vector3.one * 0.3f, 0.2f, 5, 0.5f); FadeOutAndLoad("Gameplay"); } private void OnExitButtonClicked() { exitButton.transform.DOPunchScale(Vector3.one * 0.3f, 0.2f, 5, 0.5f); FadeOutAndQuit(); } private void FadeOutAndLoad(string sceneName) { fader.raycastTarget = true; var fadeSequence = DOTween.Sequence(); fadeSequence.Join(_audioSource.DOFade(0, 0.3f).SetEase(Ease.InQuint)) .Join(fader.DOFade(1f, 0.3f).SetEase(Ease.InQuint)) .OnComplete(() => { SceneManager.LoadScene(sceneName); }); } private void FadeOutAndQuit() { fader.raycastTarget = true; var fadeSequence = DOTween.Sequence(); fadeSequence.Join(_audioSource.DOFade(0, 0.3f).SetEase(Ease.InQuint)) .Join(fader.DOFade(1f, 0.3f).SetEase(Ease.InQuint)) .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); DOTween.KillAll(); } } }