jairogarcíarincón

Introducción
Puesto que la bola se moverá en todas direcciones y sentidos y en función del lugar en el que rebote, tendríamos que calcular, en cada rebote, el ángulo de incidencia para determinar con qué ángulo debe salir rebotada.
No obstante, Unity provee de elementos que se encargan de realizar esta tarea por nosotros, como es el caso del Physics Material 2D, que nos permitirán ajustar la fricción y el rebote que se produce entre objetos 2D que colisionan.
El material 2D
- Dentro de la carpeta Materials, clic derecho Create > Physics Material 2D y llámalo MaterialBola.
- En la Inspector window, ajusta Friction a 0 y Bounciness a 1.
- Selecciona la Bola en la Hierarchy window y asígnale MaterialBola como Material del Box Collider 2D.
De esta forma, la bola rebotará cuando encuentre cualquier elemento con el que colisionar.

El script
Dentro de la carpeta Scripts, crea un nuevo C# script llamado Bola que controlará el comportamiento de nuestra bola.
Puesto que el componente MaterialBola se va a encargar de los rebotes, lo único que debemos hacer es inicializar la bola con una velocidad y dirección determinadas...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class Bola : MonoBehaviour { | |
//Velocidad | |
[SerializeField] private float velocidad = 30.0f; | |
//Se ejecuta al arrancar | |
void Start () { | |
//Velocidad inicial hacia la derecha | |
GetComponent<Rigidbody2D>().velocity = Vector2.right * velocidad; | |
} | |
} |
...y asociar el script Bola a nuestro objeto Bola.

El ángulo de colisión bola - raqueta
Con esto ya tenemos nuestra bola rebotando, si bien ahora necesitaríamos detectar en qué punto de la raqueta rebota la bola para asignar el ángulo adecuado.


Según estas dos imágenes, vemos que para calcular la velocidad de la bola:
- El valor de x será -1 si la bola rebota en la raqueta derecha
- El valor de x será 1 si la bola rebota en la raqueta izquierda
- El valor de y será 1 si la bola rebota en la parte superior de la raqueta
- El valor de y será 0 si la bola rebota en la parte central de la raqueta
- El valor de y será -1 si la bola rebota en la parte inferior de la raqueta
Entonces ¿Cómo calculo en qué punto ha rebotado?. Unity provee, para los objetos con un Box Collider 2D, el uso de la función OnCollisionEnter2D, que nos da información sobre el punto de colisión y el elemento con el que se ha colisionado.
De esta forma, podemos calcular la velocidad de la Bola si calculamos en qué posición está respecto de la raqueta, o lo que es lo mismo:
- Si la coordenada Y de la bola es mayor que la de la raqueta, rebota hacia arriba.
- Si la coordenada Y de la bola es igual que la de la raqueta, rebota de frente.
- Si la coordenada Y de la bola es menor que la de la raqueta, rebota hacia abajo.
Para ello añadiremos al script Bola una función dedicada a la que llamaremos desde OnCollisionEnter2D y otra de ayuda para calcular la dirección de salida en y llamada direccionY:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Añadir como dos nuevos métodos ANTEs de la última llave de cierre } de la clase */ | |
//Se ejecuta al colisionar | |
void OnCollisionEnter2D(Collision2D micolision){ | |
//transform.position es la posición de la bola | |
//micolision contiene toda la información de la colisión | |
//Si la bola colisiona con la raqueta: | |
//micolision.gameObject es la raqueta | |
//micolision.transform.position es la posición de la raqueta | |
//Si choca con la raqueta izquierda | |
if (micolision.gameObject.name == "Raqueta Izquierda"){ | |
//Valor de x | |
int x = 1; | |
//Valor de y | |
int y = direccionY(transform.position, micolision.transform.position); | |
//Vector de dirección | |
Vector2 direccion = new Vector2(x, y); | |
//Aplico velocidad | |
GetComponent<Rigidbody2D>().velocity = direccion * velocidad; | |
} | |
//Si choca con la raqueta derecha | |
if (micolision.gameObject.name == "Raqueta Derecha"){ | |
//Valor de x | |
int x = -1; | |
//Valor de y | |
int y = direccionY(transform.position, micolision.transform.position); | |
//Vector de dirección | |
Vector2 direccion = new Vector2(x, y); | |
//Aplico velocidad | |
GetComponent<Rigidbody2D>().velocity = direccion * velocidad; | |
} | |
} | |
//Método para calcular la direccion de Y (deevuelve un número entero int) | |
int direccionY(Vector2 posicionBola, Vector2 posicionRaqueta){ | |
if (posicionBola.y > posicionRaqueta.y){ | |
return 1; //Si choca por la parte superior de la raqueta, sale hacia arriba | |
} | |
else if (posicionBola.y < posicionRaqueta.y){ | |
return -1; //Si choca por la parte inferior de la raqueta, sale hacia abajo | |
} | |
else{ | |
return 0; //Si choca por la parte central de la raqueta, sale en horizontal | |
} | |
} |
Con esto ya tendríamos el juego funcionando, si bien todavía nos faltaría añadirle algunas cosas, tales como:
- Detectar los goles y reiniciar la posición de la bola
- Contabilizar y mostrar los goles
- Añadir sonidos
- Ir aumentando la velocidad de la bola con el tiempo
- Añadir una pantalla de inicio
- Modificar el juego para que gane el que meta 5 goles o el que meta más goles en 3 minutos (con una cuenta atrás) y volver a la pantalla de inicio al terminar con un mensaje
- Modificar la pantalla de inicio para escoger entre tiempo y número de goles
Publicado el 14 de Julio de 2025
Unity2dPong