Configuración de Física en Unity para Movimiento de Caramelos

Clase 16 de 31Curso de Desarrollo de Videojuegos para Móviles con Unity

Resumen

Domina el uso del motor de física de Unity 2D para que el intercambio tipo Candy Crush funcione solo entre piezas adyacentes. Aquí se muestra cómo desactivar autocolisiones, lanzar un raycast en cuatro direcciones, detectar vecinos con RaycastHit2D y validar si un swipe es válido. Todo con código limpio y fácil de extender.

¿Cómo configurar Physics 2D para evitar autocolisiones en Unity?

Para que el raycast no detecte el propio caramelo, debes desactivar la opción que hace que las consultas empiecen dentro del collider.

  • Ruta de menú: Edit > Project Settings > Physics 2D.
  • Opción clave: desactivar "Queries Start In Colliders".
  • Efecto inmediato: el raycast ignora el propio objeto y encuentra el vecino real.
  • Error común: si no lo desactivas, el rayo choca con el caramelo actual y el intercambio se intentará consigo mismo.

¿Cómo detectar vecinos con RaycastHit2D y Vector2?

La detección se basa en lanzar un raycast desde la posición del caramelo en una dirección dada. Si hay colisión, se toma el GameObject del collider impactado. Luego, se repite para las cuatro direcciones con un bucle foreach y una lista List.

¿Qué hace getNeighbor con RaycastHit2D?

  • Entrada: una dirección Vector2.
  • Acción: lanzar Physics2D.Raycast desde transform.position hacia esa dirección.
  • Salida: el GameObject vecino si hay colisión; si no, null.
// Dentro de la clase Candy
private GameObject GetNeighbor(Vector2 direction)
{
    RaycastHit2D hit = Physics2D.Raycast(transform.position, direction);
    if (hit.collider != null)
    {
        return hit.collider.gameObject; // vecino encontrado
    }
    return null; // no hay vecino en esa dirección
}

¿Cómo reunir todos con getAllNeighbors y foreach?

  • Recorre las cuatro direcciones del arreglo adjacentDirections.
  • Llama a GetNeighbor por cada dirección.
  • Agrega los vecinos no nulos a una lista.
private List<GameObject> GetAllNeighbors()
{
    List<GameObject> neighbors = new List<GameObject>();
    foreach (Vector2 direction in adjacentDirections)
    {
        GameObject neighbor = GetNeighbor(direction);
        if (neighbor != null)
        {
            neighbors.Add(neighbor);
        }
    }
    return neighbors;
}

Puntos clave: - Origen del rayo: transform.position. - Solo chocará con objetos que tengan collider. - En bordes, algunas direcciones no devolverán vecino.

¿Cuándo permitir el swipe entre caramelos adyacentes?

La condición es simple y robusta: el intercambio solo se permite si el caramelo previamente seleccionado está dentro de la lista de vecinos del caramelo actual. Así se garantiza que solo se mueven piezas vecinas.

¿Cómo validar con canSwipe y la lista de vecinos?

  • Comprueba si GetAllNeighbors contiene previousSelected.gameObject.
  • Devuelve true si se puede intercambiar; en caso contrario, false.
private bool CanSwipe()
{
    return GetAllNeighbors().Contains(previousSelected.gameObject);
}

¿Cómo integrar la validación en la selección y el swap?

  • En el flujo donde antes hacías el intercambio directo en el else, inserta una verificación con CanSwipe.
  • Si es válido: ejecuta SwipeSprite y deselecciona el anterior.
  • Si no es válido: deselecciona el anterior y deja seleccionado el nuevo para feedback visual.
// Fragmento ilustrativo del manejo de selección
if (previousSelected == null)
{
    SelectCandy();
}
else
{
    if (CanSwipe())
    {
        SwipeSprite();
        previousSelected.DeselectCandy();
    }
    else
    {
        previousSelected.DeselectCandy();
        SelectCandy();
    }
}

Ideas a retener: - Desactiva Queries Start In Colliders para evitar autocolisión y falsos positivos. - Usa RaycastHit2D para encontrar el primer vecino en una dirección. - Centraliza la lógica en CanSwipe para decidir si el intercambio procede. - Vecinos adyacentes: cuatro direcciones guardadas en adjacentDirections como Vector2. - Selección y feedback: solo un caramelo seleccionado a la vez; si no son vecinos, no hay intercambio.

¿Quieres que revise tu implementación de GetNeighbor o CanSwipe y te sugiera mejoras puntuales? Deja tu fragmento de código en un comentario y lo vemos juntos.

      Configuración de Física en Unity para Movimiento de Caramelos