finalizing main menu + DI container
This commit is contained in:
1 parent
b465de1bf7
commit
b974bbd843
30 files changed
+1478
-399
No files matched your search
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8752b6bb3b4c47e0ba37207aa531e459
|
||||
timeCreated: 1769496772
|
||||
@@ -0,0 +1,18 @@
|
||||
using Code.Input;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace Code.DI
|
||||
{
|
||||
public class Bootstrapper : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private InputActionAsset inputActionAsset;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
var container = new GameObject("DIContainer").AddComponent<DIContainer>();
|
||||
|
||||
container.Register<IInputService>(new InputService(inputActionAsset));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c0e2e6ddaf841588115d29a403122f9
|
||||
timeCreated: 1769496855
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Code.DI
|
||||
{
|
||||
public class DIContainer : MonoBehaviour
|
||||
{
|
||||
private readonly Dictionary<Type, object> _services = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
public void Register<T>(T service)
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (!_services.TryAdd(type, service))
|
||||
{
|
||||
Debug.LogWarning($"Service {type} is already registered.");
|
||||
}
|
||||
}
|
||||
|
||||
public T Resolve<T>()
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (_services.TryGetValue(type, out var service))
|
||||
{
|
||||
return (T)service;
|
||||
}
|
||||
throw new Exception($"Service {type} not found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4cf9b443633a411ebfc48fe9b0f981b4
|
||||
timeCreated: 1769496780
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7c1cbe75231462fb8ae7fd41e5600a9
|
||||
timeCreated: 1769496987
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Code.Input
|
||||
{
|
||||
public enum ActionMapping
|
||||
{
|
||||
MainMenu,
|
||||
UI,
|
||||
Gameplay
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e6d3a235a2d42729329b58480a6ac87
|
||||
timeCreated: 1769497003
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace Code.Input
|
||||
{
|
||||
public interface IInputService
|
||||
{
|
||||
void EnableMap(ActionMapping actionMap);
|
||||
void DisableMap(ActionMapping actionMap);
|
||||
|
||||
Vector2 MainMenuParalax { get; }
|
||||
|
||||
Vector2 LookInput { get; }
|
||||
Vector2 MoveInput { get; }
|
||||
bool SprintPressed { get; }
|
||||
|
||||
|
||||
void DebugBindAction(int mapId, int actionId, Action<InputAction.CallbackContext> action);
|
||||
void DebugUnbindAction(int mapId, int actionId, Action<InputAction.CallbackContext> action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb7a6d7e580d409aa67e2ea49ee41314
|
||||
timeCreated: 1769497026
|
||||
@@ -0,0 +1,81 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace Code.Input
|
||||
{
|
||||
public class InputService : IInputService
|
||||
{
|
||||
private readonly InputActionAsset _inputActionAsset;
|
||||
private InputAction _lmbInteractAction;
|
||||
|
||||
public Vector2 MainMenuParalax { get; private set; }
|
||||
|
||||
public Vector2 LookInput { get; private set; }
|
||||
public Vector2 MoveInput { get; private set; }
|
||||
public bool SprintPressed { get; private set; }
|
||||
|
||||
public InputService(InputActionAsset inputActionAsset)
|
||||
{
|
||||
_inputActionAsset = inputActionAsset;
|
||||
SetupInputCallbacks();
|
||||
}
|
||||
|
||||
private void SetupInputCallbacks()
|
||||
{
|
||||
SetupMainMenuInputCallbacks();
|
||||
//SetupMovementInputCallbacks();
|
||||
}
|
||||
|
||||
/*private void SetupMovementInputCallbacks()
|
||||
{
|
||||
var map = _inputActionAsset.actionMaps[(int)ActionMapping.Movement];
|
||||
BindVector2(map, "Look", v => LookInput = v);
|
||||
BindVector2(map, "Move", v => MoveInput = v);
|
||||
BindButton(map, "Sprint", v => SprintPressed = v);
|
||||
}*/
|
||||
|
||||
private void SetupMainMenuInputCallbacks()
|
||||
{
|
||||
var map = _inputActionAsset.actionMaps[(int)ActionMapping.MainMenu];
|
||||
BindVector2(map, "Parallax", v => MainMenuParalax = v);
|
||||
}
|
||||
|
||||
private void BindButton(InputActionMap map, string actionName, System.Action<bool> setter)
|
||||
{
|
||||
var action = map.FindAction(actionName);
|
||||
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
action.performed += _ => setter(true);
|
||||
action.canceled += _ => setter(false);
|
||||
}
|
||||
|
||||
private void BindVector2(InputActionMap map, string actionName, System.Action<Vector2> setter)
|
||||
{
|
||||
var action = map.FindAction(actionName);
|
||||
|
||||
if (action == null)
|
||||
return;
|
||||
|
||||
action.performed += ctx => setter(ctx.ReadValue<Vector2>());
|
||||
action.canceled += _ => setter(Vector2.zero);
|
||||
}
|
||||
|
||||
public void EnableMap(ActionMapping actionMap)
|
||||
{
|
||||
_inputActionAsset.actionMaps[(int)actionMap].Enable();
|
||||
}
|
||||
|
||||
public void DisableMap(ActionMapping actionMap)
|
||||
{
|
||||
_inputActionAsset.actionMaps[(int)actionMap].Disable();
|
||||
}
|
||||
|
||||
public void DebugBindAction(int mapId, int actionId, System.Action<InputAction.CallbackContext> action) =>
|
||||
_inputActionAsset.actionMaps[mapId].actions[actionId].performed += action;
|
||||
|
||||
public void DebugUnbindAction(int mapId, int actionId, System.Action<InputAction.CallbackContext> action) =>
|
||||
_inputActionAsset.actionMaps[mapId].actions[actionId].performed -= action;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 559062e3db0d479880c8bb1df8ea1d6c
|
||||
timeCreated: 1769497052
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5f32fb49b3adc6b6975191ad4821c68
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,162 @@
|
||||
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 showResultsButton;
|
||||
[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);
|
||||
showResultsButton.onClick.AddListener(OnShowResultsClicked);
|
||||
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), 2.4f)
|
||||
.SetLoops(-1, LoopType.Yoyo)
|
||||
.SetEase(Ease.InOutSine);
|
||||
|
||||
logotype.DOColor(new Color(originalColor.r, originalColor.g, originalColor.b, 0.9f), 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 == null) 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("Gameplay");
|
||||
private void OnShowResultsClicked() => Debug.Log("Show results");
|
||||
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);
|
||||
startGameButton?.onClick.RemoveListener(OnStartGameClicked);
|
||||
showResultsButton?.onClick.RemoveListener(OnShowResultsClicked);
|
||||
exitButton?.onClick.RemoveListener(OnExitButtonClicked);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 843de3b4de9a5c40d85b190eba05478d
|
||||
Reference in new issue
Block a user