este codigo contiene errores: a veces no mueve bien las piezas y no coloca bien la casilla vacia. Ademas no funciona el metodo si ha resuelto el puzzle: ""using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;

public class PuzzleManager : MonoBehaviour
{
public Texture2D sourceImage;
public GameObject puzzlePiecePrefab;
public int gridSize = 4;
public float spacing = 5f;


private GameObject[,] puzzlePieces;
private Vector2Int emptyPosition;

private void Start()
{
    CreatePuzzle();
    ShufflePuzzle();
}

private void CreatePuzzle()
{
    puzzlePieces = new GameObject[gridSize, gridSize];

    int pieceWidth = sourceImage.width / gridSize;
    int pieceHeight = sourceImage.height / gridSize;

    for (int y = 0; y < gridSize; y++)
    {
        for (int x = 0; x < gridSize; x++)
        {
            if (x == gridSize - 1 && y == gridSize - 1)
            {
                emptyPosition = new Vector2Int(x, y);
                continue;
            }

            GameObject piece = Instantiate(puzzlePiecePrefab, transform);
            Rect rect = new Rect(x * pieceWidth, y * pieceHeight, pieceWidth, pieceHeight);
            Sprite pieceSprite = Sprite.Create(sourceImage, rect, new Vector2(0.5f, 0.5f));

            piece.GetComponent<Image>().sprite = pieceSprite;
            RectTransform rectTransform = piece.GetComponent<RectTransform>();
            rectTransform.sizeDelta = new Vector2(pieceWidth, pieceHeight);
            rectTransform.anchoredPosition = new Vector2(x * (pieceWidth + spacing), y * (pieceHeight + spacing));

            PuzzlePiece puzzlePiece = piece.AddComponent<PuzzlePiece>();
            puzzlePiece.position = new Vector2Int(x, y);
            puzzlePieces[x, y] = piece;
        }
    }
}

public void ShufflePuzzle()
{
    int shuffleMoves = 100; // Número de movimientos aleatorios para mezclar
    for (int i = 0; i < shuffleMoves; i++)
    {
        List<Vector2Int> validMoves = GetValidMoves();
        Vector2Int move = validMoves[Random.Range(0, validMoves.Count)];
        MovePiece(move);
    }
}

private List<Vector2Int> GetValidMoves()
{
    List<Vector2Int> validMoves = new List<Vector2Int>();

    if (IsInsideGrid(emptyPosition.x + 1, emptyPosition.y)) validMoves.Add(new Vector2Int(emptyPosition.x + 1, emptyPosition.y));
    if (IsInsideGrid(emptyPosition.x - 1, emptyPosition.y)) validMoves.Add(new Vector2Int(emptyPosition.x - 1, emptyPosition.y));
    if (IsInsideGrid(emptyPosition.x, emptyPosition.y + 1)) validMoves.Add(new Vector2Int(emptyPosition.x, emptyPosition.y + 1));
    if (IsInsideGrid(emptyPosition.x, emptyPosition.y - 1)) validMoves.Add(new Vector2Int(emptyPosition.x, emptyPosition.y - 1));

    return validMoves;
}

private bool IsInsideGrid(int x, int y)
{
    return x >= 0 && x < gridSize && y >= 0 && y < gridSize;
}

public bool CanMove(Vector2Int piecePosition)
{
    return Vector2Int.Distance(piecePosition, emptyPosition) == 1;
}

public void MovePiece(Vector2Int piecePosition)
{
    Vector2Int currentEmptyPosition = emptyPosition;
    GameObject pieceToMove = puzzlePieces[piecePosition.x, piecePosition.y];

    puzzlePieces[currentEmptyPosition.x, currentEmptyPosition.y] = pieceToMove;
    puzzlePieces[piecePosition.x, piecePosition.y] = null;

    RectTransform rectTransform = pieceToMove.GetComponent<RectTransform>();
    rectTransform.anchoredPosition = new Vector2(currentEmptyPosition.x * (rectTransform.sizeDelta.x + spacing),
                                                 currentEmptyPosition.y * (rectTransform.sizeDelta.y + spacing));

    PuzzlePiece puzzlePiece = pieceToMove.GetComponent<PuzzlePiece>();
    puzzlePiece.position = currentEmptyPosition;
    emptyPosition = piecePosition;
}

public void CheckIfSolved()
{
    for (int y = 0; y < gridSize; y++)
    {
        for (int x = 0; x < gridSize; x++)
        {
            if (puzzlePieces[x, y] != null)
            {
                PuzzlePiece piece = puzzlePieces[x, y].GetComponent<PuzzlePiece>();
                if (piece.position != new Vector2Int(x, y))
                {
                    return;
                }
            } else 
            {
                Debug.Log("Es NULL");
            }
        }
    }
    Debug.Log("¡Puzzle resuelto!");
}
}

"", ""using UnityEngine;
using UnityEngine.EventSystems;

public class PuzzlePiece : MonoBehaviour, IPointerClickHandler
{
public Vector2Int position;
private PuzzleManager puzzleManager;


private void Awake()
{
    puzzleManager = FindObjectOfType<PuzzleManager>();
}

public void OnPointerClick(PointerEventData eventData)
{
    if (puzzleManager.CanMove(position))
    {
        puzzleManager.MovePiece(position);
        puzzleManager.CheckIfSolved();
    }
}
}""