| | 1 | | using System; |
| | 2 | | using System.Collections; |
| | 3 | | using UnityEngine; |
| | 4 | | using UnityEngine.EventSystems; |
| | 5 | | using UnityEngine.UI; |
| | 6 | |
|
| | 7 | | namespace DCL |
| | 8 | | { |
| | 9 | | public class NavmapZoom : MonoBehaviour |
| | 10 | | { |
| | 11 | | private const int MAX_ZOOM = 4; |
| | 12 | | private const int MIN_ZOOM = 1; |
| | 13 | | private const float MOUSE_WHEEL_THRESHOLD = 0.04f; |
| | 14 | | private const float SCALE_DURATION = 0.2f; |
| | 15 | |
|
| | 16 | | [SerializeField] private InputAction_Measurable mouseWheelAction; |
| | 17 | | [SerializeField] private RectTransform containerRectTransform; |
| | 18 | | [SerializeField] private AnimationCurve zoomCurve; |
| | 19 | |
|
| | 20 | | [SerializeField] private ZoomInput zoomIn; |
| | 21 | | [SerializeField] private ZoomInput zoomOut; |
| | 22 | |
|
| | 23 | | private int currentZoomLevel; |
| | 24 | | private bool isScaling; |
| | 25 | |
|
| 56 | 26 | | public float Scale { get; private set; } = 1; |
| 0 | 27 | | private BaseVariable<bool> navmapVisible => DataStore.i.HUDs.navmapVisible; |
| | 28 | |
|
| | 29 | | public void ResetToDefault() |
| | 30 | | { |
| 54 | 31 | | currentZoomLevel = MAX_ZOOM / 2; |
| 54 | 32 | | Scale = zoomCurve.Evaluate(currentZoomLevel); |
| 54 | 33 | | containerRectTransform.localScale = new Vector3(Scale, Scale, Scale); |
| | 34 | |
|
| 54 | 35 | | SetUiButtonsInteractability(); |
| 54 | 36 | | } |
| | 37 | |
|
| | 38 | | private void SetUiButtonsInteractability() |
| | 39 | | { |
| 54 | 40 | | zoomIn.SetUiInteractable(isInteractable: currentZoomLevel < MAX_ZOOM); |
| 54 | 41 | | zoomOut.SetUiInteractable(isInteractable: currentZoomLevel > MIN_ZOOM); |
| 54 | 42 | | } |
| | 43 | |
|
| 54 | 44 | | private void Start() => ResetToDefault(); |
| | 45 | |
|
| | 46 | | private void OnEnable() |
| | 47 | | { |
| 54 | 48 | | mouseWheelAction.OnValueChanged += OnMouseWheelValueChanged; |
| | 49 | |
|
| 54 | 50 | | zoomIn.InputAction.OnStarted += Zoom; |
| 54 | 51 | | zoomOut.InputAction.OnStarted += Zoom; |
| | 52 | |
|
| 54 | 53 | | zoomIn.Button.onClick.AddListener( () => Zoom(DCLAction_Hold.ZoomIn)); |
| 54 | 54 | | zoomOut.Button.onClick.AddListener( () => Zoom(DCLAction_Hold.ZoomOut)); |
| 54 | 55 | | } |
| | 56 | |
|
| | 57 | | private void OnDisable() |
| | 58 | | { |
| 54 | 59 | | mouseWheelAction.OnValueChanged -= OnMouseWheelValueChanged; |
| | 60 | |
|
| 54 | 61 | | zoomIn.InputAction.OnStarted -= Zoom; |
| 54 | 62 | | zoomOut.InputAction.OnStarted -= Zoom; |
| 54 | 63 | | } |
| | 64 | |
|
| | 65 | | private void OnMouseWheelValueChanged(DCLAction_Measurable action, float value) |
| | 66 | | { |
| 0 | 67 | | if (value == 0 || Mathf.Abs(value) < MOUSE_WHEEL_THRESHOLD) |
| 0 | 68 | | return; |
| | 69 | |
|
| 0 | 70 | | var zoomAction = value > 0 ? DCLAction_Hold.ZoomIn : DCLAction_Hold.ZoomOut; |
| | 71 | |
|
| 0 | 72 | | Zoom(zoomAction); |
| 0 | 73 | | } |
| | 74 | |
|
| | 75 | | private void Zoom(DCLAction_Hold action) |
| | 76 | | { |
| 0 | 77 | | if (!navmapVisible.Get() || isScaling) |
| 0 | 78 | | return; |
| | 79 | |
|
| | 80 | | switch (action) |
| | 81 | | { |
| 0 | 82 | | case DCLAction_Hold.ZoomIn when currentZoomLevel == MAX_ZOOM: |
| 0 | 83 | | case DCLAction_Hold.ZoomOut when currentZoomLevel == MIN_ZOOM: |
| 0 | 84 | | return; |
| | 85 | | } |
| | 86 | |
|
| 0 | 87 | | EventSystem.current.SetSelectedGameObject(null); |
| | 88 | |
|
| 0 | 89 | | float startScale = Scale; |
| 0 | 90 | | UpdateScale(zoomDirection: action == DCLAction_Hold.ZoomIn ? 1 : -1); |
| | 91 | |
|
| 0 | 92 | | StopAllCoroutines(); |
| 0 | 93 | | StartCoroutine(ScaleOverTime(from: startScale, to: Scale)); |
| | 94 | |
|
| 0 | 95 | | SetUiButtonsInteractability(); |
| 0 | 96 | | } |
| | 97 | |
|
| | 98 | | private void UpdateScale(int zoomDirection) |
| | 99 | | { |
| 0 | 100 | | currentZoomLevel += zoomDirection; |
| 0 | 101 | | Scale = zoomCurve.Evaluate(currentZoomLevel); |
| 0 | 102 | | MapRenderer.i.scaleFactor = Scale; |
| 0 | 103 | | } |
| | 104 | |
|
| | 105 | | private IEnumerator ScaleOverTime(float from, float to) |
| | 106 | | { |
| 0 | 107 | | isScaling = true; |
| | 108 | |
|
| 0 | 109 | | Vector3 startScale = new Vector3(from, from, from); |
| 0 | 110 | | Vector3 targetScale = new Vector3(to, to, to); |
| | 111 | |
|
| 0 | 112 | | for (float timer = 0; timer < SCALE_DURATION; timer += Time.deltaTime) |
| | 113 | | { |
| 0 | 114 | | containerRectTransform.localScale = |
| | 115 | | Vector3.Lerp(startScale, targetScale, timer / SCALE_DURATION); |
| | 116 | |
|
| 0 | 117 | | yield return null; |
| | 118 | | } |
| | 119 | |
|
| 0 | 120 | | isScaling = false; |
| 0 | 121 | | } |
| | 122 | |
|
| | 123 | | [Serializable] |
| | 124 | | private class ZoomInput |
| | 125 | | { |
| 1 | 126 | | private static Color normalColor = new Color(0f, 0f, 0f, 1f); |
| 1 | 127 | | private static Color disabledColor = new Color(0f, 0f, 0f, 0.5f); |
| | 128 | |
|
| | 129 | | public InputAction_Hold InputAction; |
| | 130 | | public Button Button; |
| | 131 | |
|
| | 132 | | [SerializeField] private Image Image; |
| | 133 | |
|
| | 134 | | public void SetUiInteractable(bool isInteractable) |
| | 135 | | { |
| 108 | 136 | | Button.interactable = isInteractable; |
| 108 | 137 | | Image.color = isInteractable ? normalColor : disabledColor; |
| 108 | 138 | | } |
| | 139 | | } |
| | 140 | | } |
| | 141 | | } |