using UnityEngine; using System.Collections.Generic; [RequireComponent(typeof(LineRenderer))] public class DrawTrail : MonoBehaviour { // --- ССЫЛКИ --- [Tooltip("Объект шарика, за которым следим")] public Transform target; private BallController ballController; // Ссылка на скрипт шарика // --- НАСТРОЙКИ ШЛЕЙФА --- [Header("Настройки Линии")] [Tooltip("Максимальное количество точек в шлейфе")] public int maxPoints = 50; [Tooltip("Минимальное расстояние между точками шлейфа")] public float pointsSpacing = 0.1f; [Tooltip("Скорость, с которой шлейф будет исчезать при окончательном приземлении")] public float fadeSpeed = 1.0f; // --- КОМПОНЕНТЫ --- private LineRenderer lineRenderer; private Material lineMaterial; // Ссылка на уникальный материал линии // --- ЛОГИКА --- private List points = new List(); private Vector3 lastAddedPointPosition; private bool isCurrentlyDrawing = false; // Флаг: сейчас рисуем новые точки? private bool isFadingOut = false; // Флаг: сейчас затухаем? void Start() { lineRenderer = GetComponent(); lineRenderer.positionCount = 0; if (target == null) { Debug.LogError("DrawTrail: Цель (Target) не установлена!", this); enabled = false; return; } // Получаем BallController с целевого объекта ballController = target.GetComponent(); if (ballController == null) { Debug.LogError("DrawTrail: На объекте Target нет скрипта BallController!", this); enabled = false; return; } // Получаем уникальный экземпляр материала для управления прозрачностью lineMaterial = lineRenderer.material; // Устанавливаем начальную прозрачность на 0, чтобы линии не было видно SetAlpha(0f); } void Update() { bool isGrounded = ballController.IsGrounded; if (!isGrounded) { // --- 1. МЫ В ВОЗДУХЕ (РИСУЕМ) --- // Если только что оторвались от земли, начинаем рисование if (isFadingOut) { // Если мы затухали, но снова взлетели (отскок) - стоп затухание isFadingOut = false; // Восстанавливаем полную непрозрачность, чтобы продолжить рисование SetAlpha(1f); } // Начинаем рисовать, если еще не рисовали if (!isCurrentlyDrawing) { isCurrentlyDrawing = true; // Сбрасываем список только если он пуст, или если прошло много времени if (points.Count == 0 || Vector3.Distance(target.position, lastAddedPointPosition) > pointsSpacing * 10) { points.Clear(); } lastAddedPointPosition = target.position; } // Добавляем точки float distance = Vector3.Distance(target.position, lastAddedPointPosition); if (distance >= pointsSpacing) { points.Add(target.position); lastAddedPointPosition = target.position; } // Всегда обновляем последнюю точку (для плавного следования) if (points.Count > 0) { points[points.Count - 1] = target.position; } // Обновляем Line Renderer lineRenderer.positionCount = points.Count; lineRenderer.SetPositions(points.ToArray()); // Ограничиваем длину шлейфа (удаляем самые старые) while (points.Count > maxPoints) { points.RemoveAt(0); } } else // isGrounded == true { // --- 2. МЫ НА ЗЕМЛЕ (ОСТАНОВКА / ЗАТУХАНИЕ) --- // Если мы только что приземлились и до этого рисовали, запускаем затухание if (isCurrentlyDrawing) { isCurrentlyDrawing = false; // Прекращаем добавлять новые точки isFadingOut = true; // Начинаем исчезать } } // --- 3. ЛОГИКА ЗАТУХАНИЯ (РАБОТАЕТ НЕЗАВИСИМО) --- if (isFadingOut) { float currentAlpha = lineMaterial.color.a; currentAlpha -= fadeSpeed * Time.deltaTime; SetAlpha(currentAlpha); // Если шлейф полностью исчез if (currentAlpha <= 0.01f) { isFadingOut = false; // Очищаем Line Renderer, чтобы он не висел невидимым points.Clear(); lineRenderer.positionCount = 0; } } } // Вспомогательный метод для установки прозрачности private void SetAlpha(float alpha) { Color color = lineMaterial.color; color.a = Mathf.Clamp01(alpha); // Убеждаемся, что альфа между 0 и 1 lineMaterial.color = color; } }