Alternative detection des collisions - Utilisons les RayCasts

Tous les tutoriaux unity, de la communauté ou d'ailleurs.
Avatar de l’utilisateur
plagas36
Messages : 23
Inscription : 13 Mai 2016 08:40

Alternative detection des collisions - Utilisons les RayCasts

Message par plagas36 » 20 Juin 2016 17:09

Bonjour,
Après avoir galéré quelques jours sur le comportement de mon personnage dans Unity, j’ai vite compris que la gestion de la physique 2D telle qu’elle est présente dans le soft ne me permettrait pas d’avoir un comportement ressemblant à celui que je voulais.
J’ai croisé pas mal de sources trouvées sur le net pendant quelques jours pour finalement arriver aujourd’hui à un compromis qui me permet de gérer collisions, pentes, grimpes et autres problèmes sans trop de problème.

Ici un petit lien qui vous mènera sur le jeu sur lequel notre équipe travaille qui utilise ces traitements : viewtopic.php?f=12&t=12694

J’ai donc décidé pour ma première fois de vous faire un petit tutoriel d’introduction à cette techno et son utilisation dans un jeu 2D.
Ce tutoriel s’adresse à des gens ayant des petites bases avec Unity. J’entends par là que vous savez créer des objets, changer la couleur du fond de la caméra, ajouter des composants et toutes les bases de ce genre.

INTRODUCTION
J’utilise exclusivement la technologie RayCast qui permet de tirer des traits virtuels dans tous les sens et d’étudier ce qu’ils ont heurté pour gérer mes collisions (retenez bien le mot trait puisque je m’en servirais partout). L’inconvénient c’est qu’il faut être un minimum callé en code, l’avantage c’est qu’on peut en lancer un paquet par frame sans qu’aucun ralentissement ne se fasse ressentir. De plus, avec quelques connaissances en math, notamment tout ce qui touche aux repères orthonormés, on peut de manière très spécifique gérer toutes les collisions de nos personnages.

C’est une alternative parfaitement viable aux détections classiques que propose Unity avec ses colliders et autres RigidBody. Elle vous permettra de gérer vos comportements, notamment sur les sols anguleux, bien plus efficacement.
Nous sommes donc en route pour toute une série de tutoriel déroulant le concept.

Image

Pour les anglicistes aimant la lecture, je vous envoie un petit lien en anglais qui vante les mérites cette technologie et qui en explique le fondement.
https://unity3d.com/learn/tutorials/top ... -practices

Dans ce premier tutoriel nous allons voir la base.
- Mettre en place un petit projet pour ce placer en situation
-> Créer une boîte qui nous servira de personnage, nous l’appellerons « Francine »
-> Placer un sol
-Créer notre premier script afin de
-> Créer une gravité
-> Ne plus passer au travers du sol

PARTIE I
Tout un programme que nous allons entamer dès maintenant. Je vous laisser ici mon outil principal que j’ai surnommé « Patrick », le 50*50 blanc fait sur Paint.
Sprite.png
Patrick le sprite magique
Sprite.png (179 octets) Consulté 2376 fois
CREATION DE FRANCINE (Vous savez le cube qui nous servira de joueur).
Image

Francine n’a rien de bien particulier. Créons simplement un objet vide. Ajoutons un « SpriteRenderer » contenant l’outil principal nommé Patrick.
Si vous ne pouvez pas placer Patrick dans la case « sprite », vérifiez qu’il n’a pas été importé en texture en cliquant sur le sprite dans la « project view » et en changeant son type si besoin dans l’« inspector ».
Ajoutons un BoxCollider2D puis désactivons-le puisque je vous rappelle que le but est de s’en passer.
Vérifions bien qu’elle est en « Layer : Default »

CREATION DU SOL
Image

Créons maintenant un sol. Il est en tout point équivalent à Francine sauf qu’il a une « Scale » en X bien supérieur et une couleur légèrement différent. Plaçons le aussi légèrement en dessous, ici en -1. De même ici, le « Layer » doit être « Default ».

On ne dirait pas comme ça, mais on est déjà à la partie deux !

PARTIE II
On va maintenant créer le script qui va gérer le comportement de Francine.
Nous appellerons ce script PlayerController.
A partir de maintenant je collerais des captures du code et je vous expliquerais ce qu’il se passe.

La gravité :
Image
1- Les variables de gravité
Ces deux variables sont plutôt simples. L’une gère l’accélération, l’autre la vitesse maximum de chute. J’ai mis 1 et 3 en valeur pour le moment.

2- La vélocité
La vélocité est publique pour que vous puissiez la voir dans l’ « inspector » mais elle devrait finir en « private ». Elle n’est pas particulièrement nécessaire pour le moment mais elle le deviendra dès que nous bougerons sur les côtés ou que nous détecterons les collisions.

3- On calcul la gravité
Ici plutôt simple, on regarde si notre vitesse est inférieure au maximum de chute. Si oui on accélère, sinon on bloque au max. Cela va nous donner un petit effet d’accélération.

4- On applique la vélocité
Il ne nous reste plus qu’à appliquer notre vélocité à Francine en translatant sa position à hauteur de la vélocité. Le « Time.deltaTime » représente le temps écoulé entre deux frames. En général, 1/30ème ou 1/60ème de seconde pour 30FPS et 60FPS.

A ce stade-là Francine devrait piquer vers le bas lorsque vous lancez la scène. Attaquons donc la grosse partie, c’est-à-dire la détection des collisions.

Détection collisions vers le bas :
Nouvelles variables
Image

Tout un tas de nouvelles déclarations :
-> « grounded » qui nous permettra de savoir si le personnage touche le sol
-> « boxCollider » pour ne pas avoir à effectuer un GetComponent chaque frame et que l’on initialise ici
-> « box » qui simplifiera grandement les traitements fournissant un tas d’informations sympa
-> « verticalRays » qui nous donnera le nombre de traits à effectuer vers le bas à chaque frame
-> « startPoint » et « endPoint » qui nous serviront de limites. J’y reviens un peu plus
-> « hitInfos » contiendra toutes les infos de collision. J’y reviens plus bas aussi.

Image

1- Initialisation de la « box »
Cette boîte est l’exacte représentation de votre boîte de collision (BoxCollider2D). Simplement « Rect » fournit tout un tas de petit outil sympa qui nous permettrons de faciliter les calculs par la suite. Notamment : « center », « bounds » que nous allons voir apparaître souvent.
Rappel sur le constructeur d’un « Rect » sous Unity ici : https://docs.unity3d.com/ScriptReference/Rect-ctor.html
Les deux derniers paramètres sont simplement la taille de la boîte. En revanche, les deux premiers sont plus complexes. Il nous faut trouver l’exacte position du coin en bas à gauche du rectangle. Pour cela, je prends la position de Francine je soustraits la moitié de la taille du BoxCollider2D pour le X et pour le Y.

Image

Note : Ce calcul ne prend pas en compte la compensation du BoxCollider2D (offset). Je le rajouterais au besoin si quelqu’un le demande.
Pour ceux qui aurait du mal à visualiser. Je fournis une petite fonction appelée DrawRect qui vous permettra de dessiner à chaque frame le Rect dans la fenêtre « Scene ». Faites des tests !!!

2- Poser les limites
Il s’agit ici de définir deux points limites. Un à gauche de notre « box » l’autre tout à droite. C’est entre ses limites que les traits de détection vont être tirés. La hauteur sera placée placé à la moitié de Francine. Histoire de pouvoir se récupérer si sa partie basse touche une plateforme.

Image

3- Taille des traits
On définit une distance de trait. Ici, on va tirer des traits partant de la moitié de Francine allant jusqu’à légèrement en dessous d’elle. Ce « légèrement en dessous » est égal à la distance parcourue en 1 frame.

4- Placer les traits
A partir d’ici on est dans une boucle. La boucle « for » n’a pas grand intérêt pour le moment puisque l’on pourrait sortir dès que l’on a touché le sol. Mais n’oublions pas que bientôt le sol ne sera plus seulement plat. Il nous faudra donc étudier tous les traits afin de connaître les angles d’impact. Tout un programme qui nous attend.
Ce bout de code sert donc à placer de manière proportionnelle le point d’origine des traits que l’on veut tirer entre les deux limites initialisées précédemment. N’hésitez pas à jouer avec « verticalRays » pour voir ce que ça donne.

5- Tirer le trait
Cette ligne de code permet de tirer le trait et d’en retirer les informations.
Décomposons chacun des paramètres nécessaires :
-> origin : le point d’origine calculé précédemment. Donc soit une limite (startPoint/ endPoint), soit entre les deux.
-> -Vector.up : dans quel sens va-t-on tracer son trait ? Et bien vers le bas pardi! Vector.Down fonctionne aussi. Mais je suis un peu taquin parfois alors je brouille les pistes.
-> Distance : La distance définit en 3. Donc la taille du trait
-> LayerMask. Ceci définit avec quel « mask » l’on souhaite que nos traits rentrent en collisions. Pour le moment, tout le monde est sur « Default » donc pas de problème. Mais pour plus tard si vous voulez faire du décor, il faudra s’en servir.

6- On a touché ?
Si « fraction » est supérieure à 0 alors nous avons touché. Pour ceux qui ont regardé la doc, tester « collider != null » fonctionnerait aussi. A savoir lequel des deux tests serait le plus optimisé en termes de temps de réponse. Personnellement je préfère tester un réel. Donc si l’on touche. « Grounded » passe à « true ».

7- Changement sur la vélocité
A partir de maintenant si on est « grounded », on ne tombe plus. Tout simplement.

CONCLUSION
A ce stade, vous devriez avoir un cube qui s’arrête au contact avec le sol. Si vous êtes impatients, vous avez en main les bases suffisantes pour faire toutes sortes de détection.
Quant à moi, je reviendrais vers vous avec la suite du tutoriel. Nous attaquerons le saut et les détections horizontales la prochaine fois.
Si vous avez des questions, des remarques, des critiques ou que vous rencontrez des problèmes, faites le moi savoir. Surtout que c’est ma première et que c’est un concept assez ardu.

Voici un lien vers une archive contenant le projet dans son intégralité. Pour ceux qui ont pas le courage de tout refaire à la main. Il contient aussi la fonction DrawRect
CollisionDetection.rar
(194.98 Kio) Téléchargé 178 fois
Je vous remercie de votre lecture.

Répondre

Revenir vers « Tutoriaux »