Cálculo de puntuación por distancia en Unity

Clase 43 de 53Curso de C# para Videojuegos

Resumen

Implementa una puntuación por distancia en Unity con un flujo claro: el jugador avanza en el eje x, la interfaz lee ese valor y la puntuación máxima se persiste con PlayerPrefs. Conecta la barra de vida, la barra de maná y el conteo de monedas con un score útil y sin sobrecargar el Update.

¿Cómo calcular la puntuación por distancia en el eje x?

Para medir la distancia recorrida basta con restar la posición x actual del jugador con su posición inicial. No necesitas aplicar el teorema de Pitágoras porque el movimiento relevante es en una sola dimensión.

  • Solo interesa el eje x: los saltos no alteran la distancia neta.
  • La distancia es positiva si avanzas a la derecha.
  • El método debe devolver un float para integrarlo como puntuación.

¿Qué es getTraveledDistance y por qué solo el eje x?

  • Devuelve la distancia total recorrida desde el inicio.
  • Ignora y porque el movimiento útil para la puntuación es horizontal.
public class PlayerController : MonoBehaviour
{
    private Vector3 startPosition;

    void Start()
    {
        startPosition = transform.position; // Punto de inicio.
    }

    public float getTraveledDistance()
    {
        // Distancia recorrida en una dimensión (eje x).
        return this.transform.position.x - startPosition.x;
    }

    // ... die() más abajo.
}

¿Cómo mostrar la distancia como score en la GameView?

  • Evita buscar el objeto cada frame: usa referencia en Start.
  • En Update, solo lee el valor ya calculado.
public class GameView : MonoBehaviour
{
    private PlayerController controller;

    void Start()
    {
        controller = GameObject.Find("player").GetComponent<PlayerController>();
    }

    void Update()
    {
        float score = controller.getTraveledDistance();
        // Actualiza la UI con "score".
    }
}

¿Cómo persistir la puntuación máxima con PlayerPrefs?

La puntuación máxima debe guardarse al morir, justo antes de reiniciar. PlayerPrefs permite leer con un valor por defecto y escribir solo si la distancia actual supera la guardada.

  • Lee con PlayerPrefs.GetFloat("maxscore", 0f).
  • Compara y guarda con PlayerPrefs.SetFloat("maxscore", valorActual).
  • Recupera el maxscore en la interfaz para mostrarlo siempre.

¿Dónde y cuándo guardar el maxscore?

  • En el método die del jugador, antes del game over.
  • Solo si traveledDistance > previousMaxDistance.
public class PlayerController : MonoBehaviour
{
    // ... startPosition y getTraveledDistance() arriba.

    private void die()
    {
        float traveledDistance = getTraveledDistance();
        float previousMaxDistance = PlayerPrefs.GetFloat("maxscore", 0f);

        if (traveledDistance > previousMaxDistance)
        {
            PlayerPrefs.SetFloat("maxscore", traveledDistance);
        }

        // Reinicia la partida o lanza el game over.
    }
}

¿Cómo recuperar maxscore en la interfaz?

  • Lee siempre con valor por defecto para evitar nulos la primera vez.
  • Muestra ambos: score actual y maxscore.
public class GameView : MonoBehaviour
{
    private PlayerController controller;
    private float maxscore;

    void Start()
    {
        controller = GameObject.Find("player").GetComponent<PlayerController>();
        maxscore = PlayerPrefs.GetFloat("maxscore", 0f);
    }

    void Update()
    {
        float score = controller.getTraveledDistance();
        // Renderiza score y maxscore en la UI.
    }
}

¿Cómo aumentar la dificultad con el LevelManager?

Si tus bloques de nivel son equiprobables, puedes sesgar la generación para que salgan más bloques complicados y el testeo sea más útil.

  • Duplica el bloque difícil varias veces.
  • Mantén un bloque inicial sencillo y varios difíciles.
  • Con 10 bloques totales y 9 difíciles, el 90% serán desafiantes.

¿Qué truco garantiza más bloques complicados?

  • En el LevelManager, registra el bloque fácil una vez.
  • Registra el bloque difícil nueve veces.
  • La probabilidad efectiva favorece al bloque difícil sin código extra.

¿Tienes dudas sobre el cálculo en el eje x, la integración en GameView o la persistencia con PlayerPrefs? Comparte tu caso y comentamos cómo ajustarlo a tu proyecto.