Skip to content

Instantly share code, notes, and snippets.

@gastoncaminiti
Created February 6, 2025 18:14
Show Gist options
  • Save gastoncaminiti/88fdc7d822ffd3bbaf955994da81aede to your computer and use it in GitHub Desktop.
Save gastoncaminiti/88fdc7d822ffd3bbaf955994da81aede to your computer and use it in GitHub Desktop.
Script para que un listado de objeto recorra un Spline
using System;
using UnityEngine;
using UnityEngine.Splines;
using System.Collections.Generic;
using System.Collections;
public class BubblesMovementManager : MonoBehaviour
{
public static BubblesMovementManager Instance { get; private set; }
[Header("Configuración del Spline Burbujas ")] [SerializeField]
private SplineContainer splineContainer;
[Header("Configuración de movimiento ")] [SerializeField]
private float speed = 1f;
[SerializeField] private float spacing = 0.1f;
[SerializeField] private float initialAdvanceSpeed = 2f;
[SerializeField] private float initialTargetProgress = 0.2f;
[SerializeField] private float repositionDuration = 0.5f;
private List<Transform> bubbles;
private float[] progress; // Progresos individuales de cada burbuja
private bool isInitialAdvance = true; // Controla si estamos en el avance inicial
private bool isMovementPaused = false;
public static EventHandler OnGameOver;
public static EventHandler OnMove;
public static EventHandler OnStop;
private void Awake()
{
if (Instance != null)
{
Debug.LogError(" Instancia duplicada de BubblesMovementManager " + transform + " - " + Instance);
Destroy(gameObject);
return;
}
Instance = this;
}
void Start()
{
BubblesMatchManager matchManager = BubblesMatchManager.Instance;
bubbles = matchManager.GetBubbles();
matchManager.OnBubbleInsert += BubblesMatchManager_OnBubbleInsert;
matchManager.OnBubblesMatch += BubblesMatchManager_OnBubblesMatch;
matchManager.OnBubblesMatchEnd += BubblesMatchManager_OnBubblesMatchEnd;
matchManager.OnBubblesReorder += BubblesMatchManager_OnBubblesReorder;
InitializeBubbleProgress();
}
void Update()
{
if (isInitialAdvance)
{
InitialAdvance();
}
else
{
if (isMovementPaused) return;
MoveBubblesAlongSpline();
}
}
private void InitializeBubbleProgress()
{
progress = new float[bubbles.Count];
for (int i = 0; i < bubbles.Count; i++)
{
progress[i] = i * spacing; // Espaciado inicial uniforme
}
}
private void InitialAdvance()
{
bool allBubblesReachedTarget = true;
for (int i = 0; i < bubbles.Count; i++)
{
// Incrementar el progreso de cada burbuja con una velocidad inicial
progress[i] += initialAdvanceSpeed * Time.deltaTime;
// Verificar si la burbuja alcanzó su progreso objetivo
if (progress[i] < i * spacing + initialTargetProgress)
{
allBubblesReachedTarget = false; // Aún hay burbujas en movimiento
}
else
{
progress[i] = i * spacing + initialTargetProgress; // Fijar al objetivo
}
// Actualizar la posición en el spline
bubbles[i].position = splineContainer.EvaluatePosition(progress[i]);
}
// Si todas las burbujas alcanzaron el objetivo, pasar al movimiento normal
if (allBubblesReachedTarget)
{
isInitialAdvance = false;
OnMove?.Invoke(this,EventArgs.Empty);
}
}
private void MoveBubblesAlongSpline()
{
for (int i = 0; i < bubbles.Count; i++)
{
progress[i] += speed * Time.deltaTime;
// Comprobar si una burbuja llega al final del spline
if (progress[i] >= 1f)
{
HandleGameOver();
return; // Salir del método para detener el movimiento
}
progress[i] %= 1f; // Mantener el progreso en el rango [0, 1]
// Ajustar el progreso para evitar superposición
if (i > 0)
{
float minProgress = progress[i - 1] + spacing;
if (progress[i] < minProgress)
{
progress[i] = minProgress % 1f;
}
}
// Actualizar la posición en el spline
bubbles[i].position = splineContainer.EvaluatePosition(progress[i]);
}
}
public void UpdateProgressAfterInsertion(int insertIndex)
{
isMovementPaused = true;
List<float> newProgressList = new List<float>(progress);
newProgressList.Insert(insertIndex, progress[insertIndex]);
progress = newProgressList.ToArray();
}
public void RecalculateProgress()
{
for (int i = 0; i < progress.Length; i++)
{
if (i > 0)
{
float minProgress = progress[i - 1] + spacing;
if (progress[i] < minProgress)
{
progress[i] = minProgress % 1f;
}
}
}
isMovementPaused = false;
}
private void HandleGameOver()
{
isMovementPaused = true; // Pausar el movimiento
Debug.Log("¡Juego terminado! Una burbuja llegó al final del spline.");
OnStop?.Invoke(this,EventArgs.Empty);
OnGameOver?.Invoke(this,EventArgs.Empty);
}
private void BubblesMatchManager_OnBubblesMatch(object sender, EventArgs empty)
{
isMovementPaused = true;
OnStop?.Invoke(this,EventArgs.Empty);
}
private void BubblesMatchManager_OnBubblesReorder(object sender, int startIndex)
{
StartCoroutine(AnimateBubblesToNewPositions(startIndex));
OnMove?.Invoke(this,EventArgs.Empty);
}
private void BubblesMatchManager_OnBubblesMatchEnd(object sender, EventArgs empty)
{
isMovementPaused = false; // Reanudar el movimiento
OnMove?.Invoke(this,EventArgs.Empty);
}
private void BubblesMatchManager_OnBubbleInsert(object sender, int startIndex)
{
UpdateProgressAfterInsertion(startIndex);
RecalculateProgress();
}
private IEnumerator AnimateBubblesToNewPositions(int startIndex)
{
Debug.Log("INDICE DE LA BURBUJA "+ startIndex);
// Verificar si hay burbujas para animar
if (startIndex == 0 || bubbles.Count == 0 || startIndex >= bubbles.Count)
{
isMovementPaused = false; // No hay burbujas, reanudar movimiento
yield break;
}
float duration = repositionDuration; // Duración de la animación (ajustable)
float floatAmplitude = 0.5f; // Amplitud del movimiento de flotación
float floatFrequency = 4f; // Frecuencia del movimiento de flotación
// Animar cada burbuja afectada (de startIndex en adelante)
for (int i = startIndex; i < bubbles.Count; i++)
{
float elapsedTime = 0f;
Vector3 startPosition = bubbles[i].position;
float startProgress = progress[i];
// Calcular el progreso objetivo relativo al progreso anterior
float targetProgress = (i == 0)
? (i * spacing)
: progress[startIndex - 1] + (i - (startIndex - 1)) * spacing;
targetProgress %= 1f;
Vector3 targetPosition = splineContainer.EvaluatePosition(targetProgress);
while (elapsedTime < duration)
{
elapsedTime += Time.deltaTime;
float t = elapsedTime / duration;
// Suavizar interpolación con Mathf.SmoothStep
t = Mathf.SmoothStep(0f, 1f, t);
// Interpolar entre el progreso inicial y el objetivo
float newProgress = Mathf.Lerp(startProgress, targetProgress, t);
Vector3 interpolatedPosition = splineContainer.EvaluatePosition(newProgress);
// Aplicar un efecto de flotación sinusoidal mientras retrocede
float floatOffset = Mathf.Sin(elapsedTime * floatFrequency) * floatAmplitude;
interpolatedPosition.y -= floatOffset;
// Actualizar la posición de la burbuja
bubbles[i].position = interpolatedPosition;
// Actualizar progreso temporalmente
progress[i] = newProgress;
yield return null; // Esperar al siguiente frame
}
// Asegurar posición final
bubbles[i].position = targetPosition;
progress[i] = targetProgress;
}
isMovementPaused = false;
}
private void OnDisable()
{
BubblesMatchManager matchManager = BubblesMatchManager.Instance;
matchManager.OnBubbleInsert -= BubblesMatchManager_OnBubbleInsert;
matchManager.OnBubblesMatch -= BubblesMatchManager_OnBubblesMatch;
matchManager.OnBubblesMatchEnd -= BubblesMatchManager_OnBubblesMatchEnd;
matchManager.OnBubblesReorder -= BubblesMatchManager_OnBubblesReorder;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment