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(); 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(); 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; } } } }