127 lines
4.3 KiB
C#
127 lines
4.3 KiB
C#
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using TMPro;
|
||
|
||
public class UIManager : MonoBehaviour
|
||
{
|
||
[Header("UI Elements")]
|
||
[SerializeField] private TextMeshProUGUI interactText;
|
||
[SerializeField] private TextMeshProUGUI speedText;
|
||
|
||
[Header("Смещение подсказки от центрального прицела")]
|
||
[Tooltip("На сколько пикселей ниже точки прицела располагается текст подсказки")]
|
||
[SerializeField] private Vector2 promptOffsetFromCenter = new Vector2(0f, -120f);
|
||
|
||
[Header("Прицел (Точка по центру экрана)")]
|
||
[SerializeField] private Image crosshairDot;
|
||
[SerializeField] private Color normalDotColor = new Color(1f, 1f, 1f, 0.8f);
|
||
[SerializeField] private Color activeDotColor = new Color(0.2f, 1f, 0.35f, 1f);
|
||
[SerializeField] private float normalDotSize = 6f;
|
||
[SerializeField] private float activeDotSize = 10f;
|
||
|
||
private RectTransform dotRect;
|
||
|
||
private void Awake()
|
||
{
|
||
EnsureCrosshairExists();
|
||
PositionPromptBelowCrosshair();
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
HidePrompt();
|
||
ToggleDashboard(false);
|
||
}
|
||
|
||
private void PositionPromptBelowCrosshair()
|
||
{
|
||
if (interactText == null) return;
|
||
|
||
RectTransform rt = interactText.rectTransform;
|
||
rt.anchorMin = new Vector2(0.5f, 0.5f);
|
||
rt.anchorMax = new Vector2(0.5f, 0.5f);
|
||
rt.pivot = new Vector2(0.5f, 0.5f);
|
||
rt.anchoredPosition = promptOffsetFromCenter;
|
||
interactText.alignment = TextAlignmentOptions.Center;
|
||
interactText.raycastTarget = false;
|
||
}
|
||
|
||
private void EnsureCrosshairExists()
|
||
{
|
||
if (crosshairDot == null)
|
||
{
|
||
Canvas canvas = GetComponentInChildren<Canvas>() ?? FindAnyObjectByType<Canvas>();
|
||
if (canvas != null)
|
||
{
|
||
GameObject dotObj = new GameObject("CrosshairDot");
|
||
dotObj.transform.SetParent(canvas.transform, false);
|
||
crosshairDot = dotObj.AddComponent<Image>();
|
||
crosshairDot.raycastTarget = false;
|
||
|
||
int res = 32;
|
||
Texture2D tex = new Texture2D(res, res, TextureFormat.RGBA32, false);
|
||
Vector2 center = new Vector2(res * 0.5f, res * 0.5f);
|
||
for (int y = 0; y < res; y++)
|
||
{
|
||
for (int x = 0; x < res; x++)
|
||
{
|
||
float dist = Vector2.Distance(new Vector2(x, y), center);
|
||
float alpha = Mathf.Clamp01((res * 0.45f - dist) * 0.8f);
|
||
tex.SetPixel(x, y, new Color(1f, 1f, 1f, alpha));
|
||
}
|
||
}
|
||
tex.Apply();
|
||
crosshairDot.sprite = Sprite.Create(tex, new Rect(0, 0, res, res), new Vector2(0.5f, 0.5f));
|
||
}
|
||
}
|
||
|
||
if (crosshairDot != null)
|
||
{
|
||
dotRect = crosshairDot.GetComponent<RectTransform>();
|
||
dotRect.anchorMin = new Vector2(0.5f, 0.5f);
|
||
dotRect.anchorMax = new Vector2(0.5f, 0.5f);
|
||
dotRect.pivot = new Vector2(0.5f, 0.5f);
|
||
dotRect.anchoredPosition = Vector2.zero;
|
||
SetCrosshairHighlight(false);
|
||
}
|
||
}
|
||
|
||
public void SetCrosshairHighlight(bool isHighlighted)
|
||
{
|
||
if (crosshairDot == null || dotRect == null) return;
|
||
crosshairDot.color = isHighlighted ? activeDotColor : normalDotColor;
|
||
float s = isHighlighted ? activeDotSize : normalDotSize;
|
||
dotRect.sizeDelta = new Vector2(s, s);
|
||
}
|
||
|
||
public void ToggleDashboard(bool isActive)
|
||
{
|
||
if (speedText != null)
|
||
speedText.gameObject.SetActive(isActive);
|
||
if (crosshairDot != null)
|
||
crosshairDot.gameObject.SetActive(!isActive);
|
||
}
|
||
|
||
public void UpdateSpeed(float currentSpeed)
|
||
{
|
||
if (speedText != null)
|
||
speedText.text = $"{currentSpeed:F0} км/ч";
|
||
}
|
||
|
||
public void ShowPrompt(string message)
|
||
{
|
||
if (interactText != null)
|
||
{
|
||
interactText.text = message;
|
||
interactText.gameObject.SetActive(true);
|
||
}
|
||
SetCrosshairHighlight(true);
|
||
}
|
||
|
||
public void HidePrompt()
|
||
{
|
||
if (interactText != null)
|
||
interactText.gameObject.SetActive(false);
|
||
SetCrosshairHighlight(false);
|
||
}
|
||
} |