En este tutorial aprenderemos a detectar un swipe (deslizamiento) en la pantalla mediante un toque en Unity. Para ello utilizaremos la clase Touch de la cual explique en este video y que nos ayudará a lograr nuestro objetivo. El swipe puede ser usado como un método de entrada alternativo para proyectos en dispositivos móviles que pueden desencadenar acciones adicionales o ser parte de las mecánicas principales.
Analizando nuestro objetivo
Necesitamos detectar cuando el usuario toque la pantalla y, sin dejar de tocarla, se deslice hacia alguna dirección. Al momento de levantar el dedo se debe determinar la dirección del swipe para ejecutar alguna acción. Podemos lograr este objetivo capturando el toque inicial y su posición, recordemos que cada toque posee las siguientes fases:
- Began: Cuando inicia el toque
- Moved: Mientras se mueve
- Stationary: Se mantiene en una misma posición
- Ended: Cuando termina el toque
- Canceled: Cuando el dispositivo cancela la detección
Con esto podemos capturar la posición del toque al iniciar y la posición del toque al finalizar, finalmente con estos dos datos podemos calcular en cuál dirección se ha realizado el swipe.
Manos a la Obra
En primer lugar declaramos el toque con el cual vamos a trabajar y dos variables de tipo Vector2 que almacenarán las posiciones de inicio y final:
private Touch touch;
private Vector2 posicion_inicial, posicion_final;
Luego necesitamos detectar cuando hay un toque en la pantalla, para ello desde el método Update() preguntaremos si la cantidad de toques es mayor a cero (0), En caso afirmativo referenciamos el primer toque detectado en nuestra variable
void Update() {
if (Input.touchCount > 0) {
touch = Input.GetTouch(0);
}
}
Ya con el toque capturado el siguiente paso es trabajar con su fase, para ello preguntaremos en que fase se encuentra con:
if (touch.phase == TouchPhase.Began) {
//Inicio del Toque
}
if (touch.phase == TouchPhase.Ended) {
//Fin del Toque
}
El último paso será calcular la dirección, y en este punto es importante tener claro como se representa la posición de un toque en la pantalla. La posición se representa en dos ejes X y Y que será el ancho y alto de la pantalla en pixeles con su punto de inicio; es decir el punto 0, en la esquina inferior izquierda.
Entonces si la posición inicial en X del toque es 100 y la final es 50 podemos determinar que el swipe fue hacia la izquierda.
Para trasladarlo al código preguntaremos si el valor inicial es mayor o menor del valor final en cada unos de los ejes:
//Preguntamos si el toque está en su fase final
if (touch.phase == TouchPhase.Ended) {
//En caso afirmativo, capturamos su posición final
posicion_final = touch.position;
//Detectamos la dirección del SWIPE a partir de esas dos posiciones
if (posicion_inicial.x < posicion_final.x) {
//SWIPE DERECHA
}
if (posicion_inicial.x > posicion_final.x) {
//SWIPE IZQUIERDA
}
if (posicion_inicial.y < posicion_final.y) {
//SWIPE ARRIBA
}
if (posicion_inicial.y > posicion_final.y) {
//SWIPE ABAJO
}
}
Puedes descargar el código de ejemplo completo al final de este post.
Más allá de lo básico
Aunque el código anterior alcanzará nuestro objetivo y puede servirte cuando deseas implementar un swipe sencillo, en proyectos de producción te encontrarás con diferentes desafíos y quisiera explicar un poco sobre ellos.
Tiempo Útil
En ocasiones en imprescindible que el proyecto pueda detectar los swipe cada cierto intervalo de tiempo, de lo contrario el usuario podría hacer gran cantidad de swipes en pocos segundos lo que podría desencadenar errores en la ejecución de las acciones que se han establecido. Para solucionarlo podemos agregar una variable adicional que capture el tiempo del último swipe y lo compare con el tiempo mínimo que deseamos, por ejemplo:
// Tiempo entre swipes
public float tiempo_requerido;
public float tiempo_ultimo_toque;
if (touch.phase == TouchPhase.Ended) {
//En caso afirmativo, capturamos su posición final
posicion_final = touch.position;
//Verificamos el tiempo transcurrido
if (Time.time < tiempo_ultimo_toque + tiempo_requerido) {
if (posicion_inicial.x < posicion_final.x) {
//SWIPE DERECHA
tiempo_ultimo_toque = Time.time;
}
if (posicion_inicial.x > posicion_final.x) {
//SWIPE IZQUIERDA
tiempo_ultimo_toque = Time.time;
}
if (posicion_inicial.y < posicion_final.y) {
//SWIPE ARRIBA
tiempo_ultimo_toque = Time.time;
}
if (posicion_inicial.y > posicion_final.y) {
//SWIPE ABAJO
tiempo_ultimo_toque = Time.time;
}
}
}
Longitud Mínima
Otro desafío es determinar la distancia mínima que queremos que se deslice el dedo para detectar el swipe, esto cuando queremos evitar que un deslizamiento mínimo se interprete como un swipe, para ello agregaremos otra variable que establezca la mínima distancia deseada y restaremos la posición final con la inicial para compararla:
// Mínima longitud que debemos arrastrar
public float longitud_minima = 20f;
private float longitud_en_x;
private float longitud_en_y;
if (touch.phase == TouchPhase.Ended) {
//En caso afirmativo, capturamos su posición final
posicion_final = touch.position;
//Calculamos longitud en cada eje
longitud_en_x = posicion_final.x - posicion_inicial.x;
longitud_en_y = posicion_final.y - posicion_inicial.y;
//Verificamos la longitud mínima en X
if (longitud_en_x > longitud_minima) {
if (posicion_inicial.x < posicion_final.x) {
//SWIPE DERECHA
}
if (posicion_inicial.x > posicion_final.x) {
//SWIPE IZQUIERDA
}
}
//Verificamos la longitud mínima en Y
if (longitud_en_y > longitud_minima) {
if (posicion_inicial.y < posicion_final.y) {
//SWIPE ARRIBA
}
if (posicion_inicial.y > posicion_final.y) {
//SWIPE ABAJO
}
}
}
Detectar una sola dirección
En el código inicial obtuvimos el acercamiento más simple para detectar un swipe, sin embargo en la mayoría de proyectos necesitamos detectar una sola dirección. Para lograr este objetivo vamos a comparar cada eje y el que tenga mayor distancia de arrastre será del cual determinaremos la dirección:
if (touch.phase == TouchPhase.Ended) {
//En caso afirmativo, capturamos su posición final
posicion_final = touch.position;
//Verificar orientación
longitud_en_x = posicion_final.x - posicion_inicial.x;
longitud_en_y = posicion_final.y - posicion_inicial.y;
//Verificamos la longitud mínima en X
if (longitud_en_x > longitud_en_y) {
//Sera en el eje X (Derecha o Izquierda)
} else {
//Sera en el eje Y (Arriba o Abajo)
}
}
Esto ha sido un acercamiento a cómo trabajar con el swipe en Unity, puedes descargar el código completo al final del post, no olvides compartir en tus redes sociales y dejar tu like. Vuelve pronto a mi blog para nuevos tutoriales y noticias. Saludos 😁