Gérer le swipe sur mobile avec Unity3D

Les smartphones d’aujourd’hui mettent à portée de doigt une puissance qui ne fait que croître. De plus, ces bijoux de technologie ont un point fort en plus de leur taille réduite : un écran tactile. Et on ne dirait pas comme ça, mais ça ouvre pas mal de portes en matière de gameplay. Tap, Swipe, Pinch… que de possibilités !

Les Gestures

Lorsque l’on travaille sur de la gestion d’inputs sur mobile, on parle souvent de « gestures ». Ce sont les gestes que l’on peut faire avec les doigts et qui seront interprétés par l’application / jeu. Ce n’est donc pas un simple appuis sur un bouton mais l’analyse de différents paramètres pour en déduire un geste :

  • Delta entre la position de départ et la position d’arrivée,
  • L’accélération du mouvement
  • Le nombre de doigts
  • etc

Unity ne propose pas de solution intégrée pour détecter des gestures. Seules les données brutes lues par les capteurs de l’écran sont disponibles, ce qui est largement suffisant pour coder soi-même des gestures simples comme un swipe.

Détecter un flick / swipe

Si sur PC vous n’avez qu’une souris, sur mobile, vous pouvez utiliser plusieurs doigts selon les capacités du smartphone. Il faut donc gérer chacun des points de contact indépendamment pour procéder à leur analyse.

Ensuite, contrairement à la souris, les points de contact ont ce que l’on appelle une phase. La phase représente l’état actuel du touch et peut prendre différentes valeurs :

  • Began : le point de touch vient d’être détecté
  • Moved : le point de touch a bougé depuis la dernière boucle d’Update
  • Stationary : le point de touch n’a pas bougé depuis la dernière boucle d’Update
  • Ended : le point de touch a disparu (l’utilisateur a relevé le doigt)
  • Canceled : le point de touch a été annulé par le système

C’est donc via tous ces états différents que nous allons pouvoir détecter le swipe (et n’importe quel gesture). Si on veut détecter un swipe, voilà la marche à suivre pour chaque phase :

  1. Began : enregistrement du point de départ du touch
  2. Ended : enregistrement du point de fin du touch et analyse

Voyons voir le script correspondant :

public class Swipe : MonoBehaviour
{
    private Vector2 startPosition;
    private Vector2 endPosition;

    private void Update()
    {
        if (Input.touchCount == 1)
        {
            var touch = Input.touches[0];
            switch (touch.phase)
            {
                case TouchPhase.Began:
                    // Stockage du point de départ
                    startPosition = touch.position;
                    break;
                case TouchPhase.Ended:
                    // Stockage du point de fin
                    endPosition = touch.position;
                    break;
            }
        }
    }
}

Ici, nous avons donc la base de détection du swipe avec l’enregistrement de la position de départ et d’arrivée. Notez que l’on ne gère qu’un seul doigt ici, mais il est tout à fait possible d’en gérer plusieurs en même temps.

Affiner la détection du Swipe

Maintenant que l’on a les informations pour détecter le swipe, il faut les analyser et décider si le gesture correspond à ce que l’on attend. Ici, le déplacement du doigt sur une distance suffisante.

Nous allons donc créer une nouvelle méthode qui va analyser le mouvement et déterminer si le swipe est « valide » :

private float swipeDistanceThreshold = 50;

private void AnalyzeGesture(Vector2 start, Vector2 end)
{
    // Distance
    if (Vector2.Distance(start, end) > swipeDistanceThreshold)
    {
        // Le mouvement est suffisamment ample
    }
}

Une nouvelle variable swipeDistanceThreshold nous permet de paramétrer la distance minimum. Ensuite la méthode effectue un calcul de distance entre les deux positions pour valider si celle ci est suffisante. On ajoute ensuite l’appel à la méthode d’analyse lors de la détection de la fin du touch :

case TouchPhase.Ended:
    // Stockage du point de fin
    endPosition = touch.position;
    AnalyzeGesture(startPosition, endPosition);
    break;

 

Référentiel de positions

Concernant le référentiel des positions retournées, le point [0,0] est situé en bas à gauche. Toujours. En images, cela vous donne le référentiel suivant :

Référentiel du touch pour détecter un swipe en mode paysage Référentiel du touch pour détecter un swipe en mode portrait

Appuyer physiquement au même endroit de l’écran en mode paysage ou en mode portrait donnera donc des positions différentes. Et si on essaie de toucher l’écran et de le tourner pour changer le mode d’affichage… il se passe quoi ? Le référentiel change, mais ce cas de figure est prévu : Unity va alors annuler le touch afin de ne pas entrer des dans situations où le touch pourrait se situer hors de l’écran. Vous aurez donc un touch avec une phase à Canceled !

Aller plus loin

Vous avez vu comment vous servir des inputs de type touch pour détecter un gesture simple. Mais si vous voulez détecter des mouvements plus complexe, la tâche se corse un peu.

Je vous recommande chaudement TouchScript disponible sur l’Asset Store. Il est gratuit, très complet, et relativement simple à prendre en main.

 

 

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *