using UnityEngine; using System.Collections.Generic; public class TrailController : MonoBehaviour { [Header("Ссылки")] [Tooltip("Префаб с компонентом TrailSegment")] public TrailSegment trailSegmentPrefab; [Tooltip("Дочерний объект с активным Line Renderer (ActiveTrail)")] public LineRenderer activeLineRenderer; private BallController ballController; [Header("Настройки")] [Tooltip("Как долго будет исчезать шлейф после касания земли (в секундах)")] public float trailFadeTime = 1.5f; [Tooltip("Минимальное расстояние между точками шлейфа")] public float pointsSpacing = 0.1f; // --- ЛОГИКА --- // Используем List для сбора точек, так как он более удобен для добавления private List currentPoints = new List(); private Vector3 lastAddedPointPosition; private bool wasGrounded = true; void Start() { ballController = GetComponent(); if (ballController == null || activeLineRenderer == null || trailSegmentPrefab == null) { Debug.LogError("Не установлены все ссылки!", this); enabled = false; } activeLineRenderer.positionCount = 0; lastAddedPointPosition = transform.position; } void Update() { bool isCurrentlyGrounded = ballController.IsGrounded; // --- 1. ЛОГИКА ОКОНЧАНИЯ СЕГМЕНТА (КАСАНИЕ) --- if (isCurrentlyGrounded && !wasGrounded) { // Шарик ТОЛЬКО ЧТО ПРИЗЕМЛИЛСЯ! int count = activeLineRenderer.positionCount; // Если есть линия для затухания (больше 1 точки) if (count > 1) { // ГЛАВНЫЙ ФИКС: // 1. Убеждаемся, что последняя точка списка — это ТОЧНОЕ место приземления. currentPoints[count - 1] = transform.position; // 2. Обновляем Line Renderer, чтобы он был отрисован корректно перед сохранением. activeLineRenderer.SetPositions(currentPoints.ToArray()); // 1. Создаем массив Vector3[] для хранения текущих позиций Vector3[] positions = new Vector3[count]; // 2. Корректно получаем позиции из LineRenderer // LineRenderer.GetPositions требует массив в качестве аргумента activeLineRenderer.GetPositions(positions); // 3. Создаем сегмент затухания TrailSegment newSegment = Instantiate(trailSegmentPrefab, Vector3.zero, Quaternion.identity); newSegment.Initialize(trailFadeTime, positions); // Передаем массив } // 4. Очищаем текущие точки и Line Renderer, готовясь к новому взлету. currentPoints.Clear(); activeLineRenderer.positionCount = 0; lastAddedPointPosition = transform.position; } // --- 2. ЛОГИКА РИСОВАНИЯ (ТОЛЬКО В ВОЗДУХЕ) --- if (!isCurrentlyGrounded) { // Шарик летит. float distance = Vector3.Distance(transform.position, lastAddedPointPosition); if (distance >= pointsSpacing) { currentPoints.Add(transform.position); lastAddedPointPosition = transform.position; } // Обновляем Line Renderer if (currentPoints.Count > 0) { // Всегда обновляем последнюю точку для плавного следования currentPoints[currentPoints.Count - 1] = transform.position; activeLineRenderer.positionCount = currentPoints.Count; activeLineRenderer.SetPositions(currentPoints.ToArray()); } } // Запоминаем состояние для следующего кадра wasGrounded = isCurrentlyGrounded; } }