153 lines
6.1 KiB
C#
153 lines
6.1 KiB
C#
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<Vector3> points = new List<Vector3>();
|
||
private Vector3 lastAddedPointPosition;
|
||
|
||
private bool isCurrentlyDrawing = false; // Флаг: сейчас рисуем новые точки?
|
||
private bool isFadingOut = false; // Флаг: сейчас затухаем?
|
||
|
||
void Start()
|
||
{
|
||
lineRenderer = GetComponent<LineRenderer>();
|
||
lineRenderer.positionCount = 0;
|
||
|
||
if (target == null)
|
||
{
|
||
Debug.LogError("DrawTrail: Цель (Target) не установлена!", this);
|
||
enabled = false;
|
||
return;
|
||
}
|
||
|
||
// Получаем BallController с целевого объекта
|
||
ballController = target.GetComponent<BallController>();
|
||
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;
|
||
}
|
||
} |