Boulet de canon. Bullet Time et Shader flou dans Unity

Ok, dans cette article, je vais faire le tour sur un des plus gros éléments que j’ai construits pour l’exercice deux. Le boulet de canon. Lors de l’impact j’attribue un Bullet Time et Shader Flou pour donner un sensation d’impact et d’électrocution du joueur.

Le boulet de canon

Pour l’élément 3D, j’ai créé un sphère 3D avec deux bandes qui donne un peu de relief. Rien de bien complexe. Ensuite j’ai ajouté quelques effets de particules et une lumière pour donner l’effet électrique.

Il y a divers appels et événements dans ce script. On va essayer d’analyser point par point.

Détruire après un temps donnée

Quand le boulet de canon apparait, par défaut il va rester sur le terrain jusqu’a la destruction. Ceci n’est pas bon pour les performances sachant qu’il y a la possibilité d’en créer des centaines. Il faut donc penser à un moyen de les détruire. Dans notre zone en dessous du terrain, il y a un bout de code qui détruit tout élément qui le touche. Mais si nos boulent ne tombent pas du terrain ?

Il y a donc un CoRoutine public qui peut être appelé lors de la création du boulet de canon avec comme variable la durée de vie. Je préfère le gérer directement par une fonction publique pour permettre une durée de vie différente en fonction de l’endroit. Par exemple, je préfère avoir une durée de vie plus longue pour des boulets qui tombent sur une rampe alors qu’un canon qui tire dans le vide ne nécessite pas d’avoir une durée de vie au-delà de deux secondes.

La petite subtilité est le fait qu’on change le bool “destroyingCanonBall”. Et dans l’Update, dès qu’on voit ce bool a True, on réduit la taille de la boule pour faire un effet de disparition. C’est mieux que de le faire disparaître brutalement.

Quand le joueur touche une boule

Ici c’est décomposé dans deux parties. Le premier est le “OnTriggerEnter()” qui se déclenche au contact. Puis on exécute un CoRoutine “lateReaction()” car il fallait implémenter des pauses pour avoir l’effet de flou et de ralentis.

Le premier chose qu’on fait est d’immobiliser le boulet pour ne pas qu’il roule pendant l’animation. On lance les effets graphiques d’éclairs, la camera qui secoue et l’effet de ralentis. Ces 3 éléments ont une durée déterminée et donc ne dépendent pas du CoRoutine pour mettre fin à l’animation.

Puis on lance la CoRoutine LateReaction qui va gérer la durée de tout le reste.

On retrouve donc la perte de vie qui appel le script sur le joueur, le son et les effets d’explosion qui démarrent après 0.7 secondes, l’effet de flou sur la camera et un nettoyage des éléments (sphère et particules d’explosion). Ça fait pas mal de code et je peux surement l’organiser mieux que ça. Mais ça fonctionne et donne l’effet voulu.

Stop, Bullet Time

Je me suis largement inspiré de ce video pour réaliser l’effet :

En bref, dans la fonction runSlowMotion, on ralentit le temps interne d’unity Time.timeScale en lui attribuant une valeur basse. Cette baisse s’exécute en appelant le fonction public runSlowMotion().

Pour éviter de ne pas impacter le moteur physique et provoquer un effet saccadé, il faut manipuler le fixedDeltaTime  pour qu’il soit toujours à 0.2F (sa valeur par défaut). Le FixedDeltaTime est le temps qui est utilisé par le moteur physique de Unity (qu’on peut utiliser dans le fixedUpdate(){}). Il faut qu’on force le temps à 0.02 par rapport au temps sinon il s’exécute trop rapidement et provoque des incohérences dans le rendu.

Ensuite, chaque frame (avec Update(){}), on augmente petit à petit la vitesse Time.TimeScale jusqu’à 1 et prenant soins de modifier le FixedDeltaTime en même temps.

Le Flou et le camera qui secoue

Bon j’envisageais d’écrire mon propre shader pour faire un effet de flou sur la camera mais en cherchant des sources, je suis tombé sur un excellent shader ici : https://github.com/PavelDoGreat/Super-Blur

Il suffit de coller le script SuperBlur.cs sur la camera, appliquer le matériel et le tour est joué. on applique l’effet en activant et désactivant le script (je pourrais aussi faire un vérification “if electrocuted” mais j’ai trop la flemme !!!)

Du coup je me rabats sur un petit script qui va secouer la camera

Rien de bien sorcier ici, on a un CoRoutine public qui s’appelle ShakePosition(). Lors du démarrage, on enregistre la position du camera afin de le remettre après que la camera a bougé.

Pour l’effet, on modifie le Transform du camera avec un PerlinNoise pour avoir un mouvement fluide et on se base sur le temps du jeu pour définir les points dans la map Perlin pour donner un coté aléatoire.

 

One thought on “Boulet de canon. Bullet Time et Shader flou dans Unity

Leave a Reply

Your email address will not be published. Required fields are marked *