Contenido del curso

Mecánica Principal

Intercambio de piezas con arrays 2D en Unity

Resumen

Mover piezas en un tablero de Unity requiere algo más que animarlas: necesitas un sistema que actualice sus coordenadas cada vez que cambien de lugar. Aquí aprendes a usar arrays bidimensionales en Unity para registrar tiles y piezas, detectar el input del mouse y ejecutar el intercambio entre dos casillas.

Esta guía te sirve si estás construyendo un juego tipo match-3, puzzle o cualquier proyecto con cuadrícula donde las piezas deban intercambiar posiciones manteniendo coherencia interna.

Qué son los arrays bidimensionales y por qué los usamos para una cuadrícula

Un array normal guarda elementos en una sola fila y los accedes con un índice. Un array bidimensional funciona como una cuadrícula virtual con eje X y eje Y, exactamente igual a tu tablero en pantalla.

Para declararlos en C# usas corchetes con una coma dentro:

csharp Tile[,] tiles; Piece[,] pieces;

Esa coma es la clave. Le dice al compilador que vas a pasar dos índices cuando quieras acceder a un elemento. Uno para la columna, otro para la fila.

¿Qué es un array bidimensional en C#? Es una estructura de datos con dos índices, uno por eje. Lo declaras con Tile[,] y accedes a un elemento con tiles[x, y], igual que una coordenada en un plano.

Cómo guardar tiles y piezas dentro del array bidimensional

En la función setupBoard, cada vez que creas un tile guardas su referencia en el array antes de llamar a su función setup:

csharp tiles[x, y] = tile; tiles[x, y].Setup(...);

La misma lógica aplica para setupPieces: asignas la pieza al array pieces[x, y] y luego llamas a su setup desde esa referencia almacenada. Con esto, ambos arrays contienen toda la información del tablero en cualquier momento del juego [02:30].

Cómo detectar clic y arrastre del mouse para mover piezas

El flujo de interacción tiene tres momentos: clic inicial, arrastre sobre otra casilla y soltar el mouse. Necesitas una función para cada evento.

Las tres funciones del board: TileDown, TileOver y TileUp

Dentro de la clase Board defines:

  • TileDown(Tile tile_): guarda la casilla inicial en una variable startTile.
  • TileOver(Tile tile_): actualiza endTile con la casilla sobre la que pasa el mouse.
  • TileUp(Tile tile_): verifica que ambas existan y dispara el intercambio.

La verificación en TileUp es importante. Si startTile o endTile son nulos, no debe pasar nada. Si ambos tienen valor, llamas a SwapTiles() y luego reinicias ambas variables a null para dejar el sistema listo para el siguiente movimiento [04:50].

Cómo detectar el input desde la clase Tile

Unity ofrece funciones nativas que también funcionan en dispositivos móviles. En el script de la tile agregas:

csharp public void OnMouseDown() { board.TileDown(this); } public void OnMouseEnter() { board.TileOver(this); } public void OnMouseUp() { board.TileUp(this); }

Cada función envía una referencia de sí misma con this al board. Para que Unity dispare estos eventos, el prefab de la tile necesita un collider, por ejemplo un Box Collider 2D, ligeramente más pequeño que el sprite para evitar clics que se filtren al vecino.

Cómo funciona la función SwapTiles para intercambiar piezas

La función SwapTiles hace dos cosas: mueve las piezas en pantalla y actualiza el array bidimensional para que el sistema de coordenadas siga siendo verdadero.

Primero obtienes referencias a las piezas involucradas:

csharp var startPiece = pieces[startTile.x, startTile.y]; var endPiece = pieces[endTile.x, endTile.y];

Luego mueves cada pieza a la posición opuesta llamando a su función Move. Y por último, actualizas el array para que la pieza inicial ocupe la posición final y viceversa:

csharp pieces[startTile.x, startTile.y] = endPiece; pieces[endTile.x, endTile.y] = startPiece;

Si olvidas este paso, las piezas se moverán visualmente pero el array seguirá pensando que están en su posición original. La próxima vez que intentes intercambiarlas, todo se romperá [07:40].

¿Por qué hay que actualizar el array después de mover las piezas? Porque la posición visual y la lógica son cosas distintas. El array es la fuente de verdad del juego, y si no lo actualizas, futuras consultas devolverán datos incorrectos.

Por qué aparece el error NullReferenceException al ejecutar

Un error común al dar play es ver en consola un mensaje sobre un objeto referenciado sin instancia. La causa: declaraste los arrays pero nunca los inicializaste.

La solución va en la función Start:

csharp tiles = new Tile[width, height]; pieces = new Piece[width, height];

Usas el ancho y el alto de tu cuadrícula como dimensiones. Sin esta línea, los arrays existen como variables pero no tienen espacio reservado en memoria, por eso fallan al asignar el primer tile [09:30].

¿Qué significa Object reference not set to an instance of an object? Significa que estás intentando usar una variable que nunca fue inicializada con new. En arrays bidimensionales, debes asignarles tamaño antes de guardar elementos.

Qué falta para limitar el movimiento entre piezas

En este punto puedes hacer clic en cualquier pieza, soltar sobre otra y se intercambian, sin importar la distancia. Eso no es lo que queremos en un match-3 real, donde solo deben moverse piezas adyacentes.

Esa restricción la trabajaremos en la siguiente clase. Si tuviste dudas con el sistema de coordenadas o con cómo se sincronizan los arrays con el movimiento visual, déjalas en los comentarios.