136 lines
4.6 KiB
C#
136 lines
4.6 KiB
C#
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
public class MenuEcholocationRadar : MonoBehaviour
|
||
{
|
||
[Header("Настройки волн эхолокации (Мягкие облака)")]
|
||
public int maxSimultaneousWaves = 3;
|
||
public float waveMaxRadius = 1800f;
|
||
public float waveSpeed = 180f;
|
||
public float waveSpawnInterval = 2.4f;
|
||
public float initialThickness = 110f;
|
||
public float maxThickness = 360f;
|
||
|
||
[Header("Цветовая палитра волн (Мягкий золотистый туман)")]
|
||
public Color waveBaseColor = new Color(1.00f, 0.82f, 0.18f, 0.40f); // Теплая янтарная дымка
|
||
public Color waveCoreColor = new Color(1.00f, 0.94f, 0.50f, 0.65f); // Мягкое золотистое ядро
|
||
public Color beaconColor = new Color(1.00f, 0.88f, 0.20f, 0.85f);
|
||
|
||
[Header("Радарный маяк (В углу экрана)")]
|
||
public Image radarBeaconDot;
|
||
public Image radarReticle;
|
||
|
||
private class WaveInstance
|
||
{
|
||
public MenuEchoWaveRenderer renderer;
|
||
public float radius;
|
||
public bool active;
|
||
public float delay;
|
||
}
|
||
|
||
private WaveInstance[] waves;
|
||
private float spawnTimer = 0f;
|
||
|
||
private void Awake()
|
||
{
|
||
InitializeWaves();
|
||
}
|
||
|
||
private void InitializeWaves()
|
||
{
|
||
waves = new WaveInstance[maxSimultaneousWaves];
|
||
|
||
for (int i = 0; i < maxSimultaneousWaves; i++)
|
||
{
|
||
GameObject waveObj = new GameObject($"EchoWave_{i + 1}");
|
||
waveObj.transform.SetParent(transform, false);
|
||
|
||
RectTransform rt = waveObj.AddComponent<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 = Vector2.zero;
|
||
|
||
MenuEchoWaveRenderer renderer = waveObj.AddComponent<MenuEchoWaveRenderer>();
|
||
renderer.raycastTarget = false;
|
||
|
||
waves[i] = new WaveInstance
|
||
{
|
||
renderer = renderer,
|
||
radius = 0f,
|
||
active = false,
|
||
delay = i * waveSpawnInterval // Заранее распределяем фазы волн
|
||
};
|
||
}
|
||
}
|
||
|
||
private void Update()
|
||
{
|
||
float dt = Time.unscaledDeltaTime;
|
||
|
||
// Запуск первой волны сразу, остальных — по интервалу
|
||
spawnTimer += dt;
|
||
if (spawnTimer >= waveSpawnInterval)
|
||
{
|
||
spawnTimer = 0f;
|
||
TriggerNextWave();
|
||
}
|
||
|
||
// Обновление всех активных волн
|
||
for (int i = 0; i < waves.Length; i++)
|
||
{
|
||
var w = waves[i];
|
||
if (!w.active) continue;
|
||
|
||
w.radius += waveSpeed * dt;
|
||
float progress = Mathf.Clamp01(w.radius / waveMaxRadius);
|
||
|
||
// Плавное появление (Fade-in) в начале и глубокое мягкое растворение (Fade-out)
|
||
float fadeIn = Mathf.SmoothStep(0f, 1f, progress / 0.18f);
|
||
float fadeOut = Mathf.Pow(1f - progress, 1.25f);
|
||
float alpha = fadeIn * fadeOut;
|
||
|
||
// Расширение полосы с увеличением радиуса (мягкое рассеивание облака тумана)
|
||
float currentThickness = Mathf.Lerp(initialThickness, maxThickness, Mathf.Sqrt(progress));
|
||
|
||
w.renderer.SetWave(w.radius, currentThickness, alpha, waveBaseColor, waveCoreColor);
|
||
|
||
if (w.radius >= waveMaxRadius)
|
||
{
|
||
w.active = false;
|
||
w.radius = 0f;
|
||
w.renderer.SetWave(0f, 0f, 0f, waveBaseColor, waveCoreColor);
|
||
}
|
||
}
|
||
|
||
// Пульсация маяка в центре радара
|
||
if (radarBeaconDot != null)
|
||
{
|
||
float pulse = Mathf.PingPong(Time.unscaledTime * 2.5f, 1f);
|
||
float scale = Mathf.Lerp(0.85f, 1.25f, pulse);
|
||
radarBeaconDot.transform.localScale = new Vector3(scale, scale, 1f);
|
||
Color c = beaconColor;
|
||
c.a = Mathf.Lerp(0.5f, 1f, pulse);
|
||
radarBeaconDot.color = c;
|
||
}
|
||
|
||
if (radarReticle != null)
|
||
{
|
||
radarReticle.transform.Rotate(0f, 0f, -12f * dt);
|
||
}
|
||
}
|
||
|
||
private void TriggerNextWave()
|
||
{
|
||
for (int i = 0; i < waves.Length; i++)
|
||
{
|
||
if (!waves[i].active)
|
||
{
|
||
waves[i].active = true;
|
||
waves[i].radius = 0f;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|