110 lines
4.0 KiB
C#
110 lines
4.0 KiB
C#
using System.Collections;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
public class DrawVisual : MonoBehaviour
|
||
{
|
||
[Header("Refs")]
|
||
[SerializeField] private Image panel;
|
||
//[SerializeField] private Image lamp;
|
||
[SerializeField] private TextMeshProUGUI maintext;
|
||
|
||
[Header("Speeds")]
|
||
[SerializeField] private float curtainSpeed = 3f; // скорость изменения высоты
|
||
[SerializeField] private float scaleSpeed = 3f; // скорость изменения масштаба текста
|
||
[SerializeField] private float blinkFreq = 2f; // герцы мерцания
|
||
|
||
private void Start()
|
||
{
|
||
Hide();
|
||
}
|
||
|
||
public void Show()
|
||
{
|
||
StopAllCoroutines(); // гасим всё, что крутилось до этого
|
||
StartCoroutine(OpenAnimation()); // последовательная анимация
|
||
StartCoroutine(Blink(maintext, 0.4f, 1f));
|
||
//StartCoroutine(Blink(lamp, 0.4f, 1f));
|
||
}
|
||
|
||
public void Hide()
|
||
{
|
||
StopAllCoroutines();
|
||
StartCoroutine(CloseAnimation()); // обратный порядок
|
||
StartCoroutine(Blink(maintext, 0.4f, 1f));
|
||
//StartCoroutine(Blink(lamp, 0.4f, 1f));
|
||
}
|
||
|
||
// ===== Sequences =====
|
||
|
||
IEnumerator OpenAnimation()
|
||
{
|
||
// Сначала шторка, потом текст
|
||
yield return SetCurtainHeight(2.7f, curtainSpeed);
|
||
yield return SetTextScale(1f, scaleSpeed);
|
||
}
|
||
|
||
IEnumerator CloseAnimation()
|
||
{
|
||
// Обратный порядок: сначала текст схлопывается, потом шторка
|
||
yield return SetTextScale(0f, scaleSpeed);
|
||
yield return SetCurtainHeight(0f, curtainSpeed);
|
||
}
|
||
|
||
// ===== Anim pieces =====
|
||
|
||
// Шторка: меняем визуальную высоту (учитывает anchors)
|
||
IEnumerator SetCurtainHeight(float targetHeight, float speed)
|
||
{
|
||
var rt = panel.rectTransform;
|
||
const float EPS = 0.01f;
|
||
|
||
// Берём текущее визуальное значение, а не sizeDelta (надёжнее при разных якорях)
|
||
while (Mathf.Abs(rt.rect.height - targetHeight) > EPS)
|
||
{
|
||
float current = rt.rect.height;
|
||
float next = Mathf.MoveTowards(current, targetHeight, speed * Time.deltaTime);
|
||
rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, next);
|
||
yield return null;
|
||
}
|
||
|
||
// Финальное выравнивание
|
||
rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, targetHeight);
|
||
}
|
||
|
||
// Текст: масштаб только по Y (оставляем X/Z как есть)
|
||
IEnumerator SetTextScale(float targetScaleY, float speed)
|
||
{
|
||
var rt = maintext.rectTransform;
|
||
const float EPS = 0.001f;
|
||
|
||
while (Mathf.Abs(rt.localScale.y - targetScaleY) > EPS)
|
||
{
|
||
float y = Mathf.MoveTowards(rt.localScale.y, targetScaleY, speed * Time.deltaTime);
|
||
rt.localScale = new Vector3(rt.localScale.x, y, rt.localScale.z);
|
||
yield return null;
|
||
}
|
||
|
||
rt.localScale = new Vector3(rt.localScale.x, targetScaleY, rt.localScale.z);
|
||
}
|
||
|
||
// Бесконечное мерцание альфы между min и max
|
||
IEnumerator Blink(MaskableGraphic graphic, float minAlpha, float maxAlpha)
|
||
{
|
||
// Нормализация входа
|
||
minAlpha = Mathf.Clamp01(minAlpha);
|
||
maxAlpha = Mathf.Clamp01(maxAlpha);
|
||
if (maxAlpha < minAlpha) (minAlpha, maxAlpha) = (maxAlpha, minAlpha);
|
||
|
||
float amplitude = maxAlpha - minAlpha; // раньше было max - max → 0 (баг)
|
||
while (true)
|
||
{
|
||
Color c = graphic.color;
|
||
// Используем unscaledTime, чтобы мерцание не зависело от Time.timeScale
|
||
c.a = minAlpha + Mathf.PingPong(Time.time * blinkFreq, amplitude);
|
||
graphic.color = c;
|
||
yield return null;
|
||
}
|
||
}
|
||
} |