site :
https://chronoshift-jeu.netlify.app/#sectionAccueil
Chronoshift est un jeu de donjon hack'n slash où vous arrêtez le temps pour vaincre des ennemies et résoudre des puzzles.
Mes rôles étaient directeur artistique et chargé de projet.
J'ai programmé les mouvements et la mécanique de pick-up d'objets physiques et de lancer pour joueur.
J'ai conceptualisé et animé les personnages et assemblé le niveau 2.
C'est un projet de technique du TIM que j'ai fait en équipe :
- Adib Benchekroun (Chargé de projet - Direction Artistique - Intégration)
- Ariane Laferrière-Martineau (Chargée de projet)
- Krisitan Chung (Responsable UX - Conception Sonore)
- Geoffroi Henquin (Direction Technique - Responsable de l'Archivage)
Mes tâches
- Gestion et documentation de projet
- Programmation de character controller / ennemis
- Animation de personnages
- Design de niveau 2 et puzzles
J'ai codé les mécaniques de gameplay comme le character controller, les ennemis et les 2 dernières salles de puzzle.
J'ai aussi animé les personnages et designé le niveau 2. Je n'ai pas codé le "Time Stop" du jeu au passage, c'était l'ajout de Geoffroi Henquin !
Voilà le premier puzzle que j'ai designé et Programmé pour le jeu. J'ai du programmer une transition de ode caméra pour monter une vue d'ensemble sur la sale et faire en sorte que le boutton change l'état du pond et de la porte lorsqu'il est appuyé.
C'est une salle où le joueur doit se rendre à la porte mais pour l'ouvrir, il doit garder le bouton rouge au sol appuyé. Pour se faire il doit poser un bloc dessus mais lorsque le bouton est activé, la porte s'ouvre mais le chemin vers la porte est descendu. Le joueur doit donc amener la boîte au bouton mais arrêter le temps pendant que le cube est en train de tomber pour avoir le temps de passer le pond et ensuite laisser le cube tomber pour ouvrir la porte.
C'est un puzzle qui nécessite au joueur d'analyser l'environnement et de comprendre par ses actions, ce qui change lorsqu'il appuit sur le switch donc j'ai implémenté un repositionnement de la caméra pour cadrer toute la salle afin que le joueur puisse faire une corrélation instantannée avec les résultats de ses actions.
J'ai designé ce puzzle avec l'intention qu'il tourne autour de la mécanique principale de time stop, il fallait alors que le joueur soit obligé d'utiliser cette mécanique pour progresser, en somme, ce système à bien fonctionné mais maintenant que je révise ce projet, je pense qu'il aurait été plus mieux d'ajouter un des murs passables qui détruisent les objets (montré dans le prochain puzzle) sur le côté de l'étage supérieur pour empêcher les joueurs de jeter leur boîte au boutton depuis la porte après avoir passé le chemin.
Dans ce puzzle, le joueur doit encore poser une boîte sur le bouton afin de garder la porte de sortie ouverte, cependant, lorsque le joueur retourne au bout de salle pour collecter une boîte et l'emmenner à sa destination, sa boîte est détruite dès qu'il passe à travers le mur bleu qu'on a positionné entre les boîtes et le cube. Le seul moyen de désactiver ce mur est d'appuyer sur l'autel qui rayonne en rouge après le mur. Lorsque le joueur appuit dessus, le mur se baisse mais quand il quitte l'autel, le mur revient. La solution est donc de ramasser une boîte, la jeter au mur et arrêter le temps avant qu'elle touche ce dernier pour aller le désactiver en appuyant sur l'alter et activer le temps pour laisser la boîte reprendre son momentum pour se diriger vers l'autre côté.
Dans les premiers stages d'idéation du jeu, j'ai conceptualisé un scénarimage qui présente les mécaniques du jeu. On y voit le système de sort et de magie qu'on a dû abandonner pour le scope mais on y voit aussi la visualisation de la mécanique principale du jeu qui est d'arrêter le temps et de le faire continuer à volonté.
Rail-O-Vania est une application mobile que moi, David Dias, et Frédérick Ducher avont créée pour un GameJam de 48 heures.
Pour ce projet, J'ai designé et assemblé le niveau et chemin de course du wagon.
C'est un chemin relativement court donc je voulais que le joueur change d'environnement assez rapidement et qu'il ait de quoi à faire. Alors le chemin commence lentement dans une section étroite pour qu'il ait le temps de s'accommoder aux contrôles, ensuite le joueur passe à travers une section rapide sur un précipice au-dessus de la lave qui l'emmène vers une grotte où il doit tirer à distance sur un levier pour faire descendre le pond qui lui permet de progresser. Cette section était implémentée car on voulait enrichir l'expérience avec plus d'interaction avec l'environnement, cependant on a manqué de temps mais cette section reste engageante.
je me suis aussi occupé de la modelisation des assets comme les rails et vagons, les chauves sourris et les infrastructures à l'exception de la cabane du début.
Projet 3D que j'ai fait pour la technique en hiver 2019, c'est un véhicule aérien que j'ai modélisé sur Maya et qui tire son apparence des aspects physiques d'une baleine. Je l'ai conceptualisé et modelé pour qu'il fasse partie d'un plus grand narratif.
Projet 3D que j'ai fait pour la technique en hiver 2019 dans un projet d'équipe de 4 où on devait conceptualiser des personnages qui auraient un narratif ensemble, c'est un personnage que j'ai modélisé, riggé et animé sur Maya.
Projet 3D que j'ai fait pour la technique en hiver 2019, c'est un pistolet à portail que j'ai conceptualisé et modélisé sur Maya. J'ai conceptualisé et modeler cet objet pour qu'il entre dans le narratif d'un univers inventé.
Une animatique que j'ai réalisé avec David Dias pour un cours de scénarisation, c'est un petit clip avec un scénario qui raconte la petite histoire d'un petit garçon qui se trouve un ami, j'ai fait le scénarimage et dessin de l'animatique pour ce projet.
Animation que j'ai fait pour un cours de montage sur After Effects dans le contexte de créer une intro pour un projet de technique.
2018 - C'est une courte Animation d'intro pour le jeu Rivals of Aether (ce n'est pas mon jeu et je 'ai aucun droit dessus'), j'ai monté cette animation tôt dans ma technique sur Adobe flash.
C'est ma première animation sur Adobe After Effects, je l'ai fait pour un cours de montage vidéo sur ce logiciel.
Warriors Arena est un jeu shooter Runner Gunner PVP fait pour un GameJam de 48 heures fait à l'UQAT. Le jeu a été conçu avec Alain Pham, David Dias et Antoine Turgeon.
Voîlà le roster de personnages et la map que j'ai conceptualisé pour ce jeu.
Deux maquettes que j'ai conçues pour le personnage joueur de Chronoshift durant le stage d'idéation du projet. À la première itération, il y avait peu d'inspiration derrière le design mais suite aux idées et suggestions de mes collègues, le personnage est devenu plus intéressant et plus tranché sur son design.
Chronoshift est un projet que j'ai fait en équipe de 4 pour la technique du TIM avec :
Ariane Laferrière-Martineau,
Krisitan Chung,
Geoffroi Henquin
J'ai aussi fait des maquettes pour les ennemis. vers le milieu du projet, les choses commençaient à aller vite donc je devait mettre des idées sur papier assez rapidement, c'est pour ça que beaucoup d'éléments de design ont été recyclés et mélangés pour créer des nuances et un langage visuel consistant.
Un téléphone propre à un monde semi-fantaisique que j'ai modélisé et texturé dans le contexte d'un cours d'initiation à la 3D à l'UQAT.
Lien du jeu :
https://megaxalain.itch.io/tobor
Tobor est un jeu de plateforme dans lequel le joueur incarne un robot à le recherche de sa jambe perdue dans une usine de jouet.
C'est un projet de l'UQAT pour lequel j'ai travaillé dans une équipe de 9.
Équipe
Design
- Audrey-Rose Lemay B
- Julien Lapointe
- Sodana Yen
Art
- Anthony Techer
- Jonathan Bezeau
- Thomas Clermont
- Sidney Tork
Tech
- Alain Pham
- Adib Benchekroun
Mes tâches
- Programmer des mécaniques interactives de l'environnement
- Intégrer Assets 3D
- Assurer fonctionnement d'évenements scriptés et cinématiques
Voîlà un exemple de Tapis roulants que j'ai dû intégrer et programmer pour le jeu. Ils poussent tous les objets physicalisés dans la direction de la texture puis la direction de la vélocité et de la texture est réversible. Pour les rendre plus intéressants visuellement, j'ai rapidement programmer des "spawner" de legos aléatoires au pied des tapis roulants.
J'ai programmé la séquence de poursuite à la fin du jeu en utilisant l'outil sequencer de Unreal. Pour cette séquence, j'ai manuellement scripté les mouvements du drone et de la caméra avec des keyframes de façon à ce que cette partie du niveau ai une allure plus cinématique. Le résultat est plus ou moins réussi. En somme, le drone et la caméra laissent assez de temps au joueur pour réagir et se faire un chemin tout en restant dans le cadre de l'écran mais un jouer abile est capable de dépasser la caméra. C'est un problème qu'on aurrait pu résoudre avec assez de temps pour réviser notre approche à l'intégration de cette séquence, le fait qu'on était en période de crunch a fait qu'on était laissé avec peu d'options. Le mieux aurrait été de priorisé cette séquence avant les autres tâches et programmer une caméra dynamique qui suiverait le joueur.
En collaboration avec Alain Pham, on a programmé cette séquence d'interactibilité où le joueur appui sur le boutton pour activer la réorgannisation des plateformes en escalier pour progresser à la prochaine partie du niveau.
C'est un projet que j'ai fait dans le contexte d'un atelier dirigé à l'UQAT. J'avais l'objectif de créer un character controller qui mélange les mécaniques de ski et de grappin. Pour se déplacer, le joueur doit donc accumuler de la vélocité en accrochant son grappin a des objets comme des arbres et appuyer sur click gauche pour se laisser tirer vers l'objet pendant qu'il ski.
Pour la mécanique de ski, j'ai utilisé une capsule rigidbody aucun drag et un physics material avec 0 friction lorsque le joueur appui sur Shift.
Le grappin est fait d'un spring joint avec des parametres ajustés et le joueur est tiré vers son point d'ancrage à l'aide d'un "AddForce" qui soustrait sa position à celle du point d'anchrage afin de laisser le joueur se balancer pendant qu'il gagne de la vélocité vers le point d'origine du grappin.
Le terrain a été modélisé à la main avec l'outil de terrain Unity et les assets ont été importé du Asset Store Unity.
Amphibian Rescue est un jeu de plateforme Coop ou les joueurs incarnes des grenouilles. Voici quelques concepts et variations pour les personnages que les joueurs allaient incarner. C'est un projet annulé.
Équipe :
Alexandre Tanasie,
Antoine Turgeon,
Félix Poirier,
Sophie Bauer,
Emi Larralde Castillo,
Maude Filiatraut,
Olivier Barbeau
Voilà quelques "early" concepts que j'ai fait pour un équipage spatial de scientifiques pour le jeu The Obscura Experiment, un projet de jeu UQAT
Page Steam :
https://store.steampowered.com/app/2290480/The_Obscura_Experiment/
The Obscura Experiment est un projet de finnisant UQAT qui devrait être publié sur Steam le 7 Mars. C'est un jeu d'horreur sci-fi qui prend place dans un vaissau où une expérience scientifique a tourné au mal. L'équipage a été anéanti par une anomalie à la recherche d'énergie et le joueur doit maintenant utiliser tous les outils à sa disposition pour survivre.
Équipe
Design
- Julien Lapointe
- Antoine Turgeon
- Alexander Tanasie
- Alexandre Séguin
- Maude Martel
- Jordan Lapointe
- Jean-Philippe Filiatrault
- Arnaud Léveillé
Art
- Jordan Dion-Duval
- Antoine Kwey-Du Sablon
- Kimberly Victoria
- Renée-Claude Séguin
- Sidney Torck
- Jonathan Bezeau
- Elsie Yip
- Victor-Emmanuel Burelle
Tech
- David Dias
- Alain Pham
- Adib Benchekroun
- Antoine Turgeon
- Jean-Philippe Filiatrault
- Isaac Roy
- Antonin Doucet
Mes tâches
- Programmation de Minimap adaptable
- Systême de caméras intéractif
- Développement d'outils de construction niveau pour Artists
- Travailler avec Designers et Artists pour intégrer mécanniques et fonctionnalités
Minimap Procédural interactif et Systême de caméras dynamiques. J'ai codé le UI de la tablette au centre de contrôle, la minimap qui se dessine selon le layout du niveau et le systême de caméras de surveillance. Pour ça, j'ai du programer un custom widget qui génère un layout du niveau indiquant la position du joueur et des différents éléments de la map puis rendre le tout interactible pour laisser le joueur sélectionner les différentes caméras du niveau.
La Minimap n'est pas pré-déssinée, elle est vide au départ et prend la forme du niveau selon le layout des murs, au départ le jeu allait avoir des niveaux procéduraux donc j'ai du programmer cette minimap pour être dynamique et capable de se redessiné selon la forme actuel des murs du niveau.
Mon Processus
Pour afficher la minimap, j'ai utilisé un custom widget avec un border dans lequel j'affiche des images en forme de lignes qui réplique la longueur, rotation et position des murs du niveau. Pour ce faire, j'ai regrouppé les murs par leurs tags, je compare leurs position en X et Y pour définir les extremités du niveau.
Ensuite, une boucle foreach cycle à travers tous les murs pour construire une image qui match la taille, rotation et position du mur, la position et taille du murs dans le niveau sont converti en unités de widget pour être affichés dans le border.
Les bouttons de caméra sont affichés de la même façon, mais au lieu de construire une image, j'ai fait un custom widget qui affiche un boutton dans lequel une référence à la caméra d'une salle est appelé lorsqu'on appuis sur le boutton.
Étape 1 - Setup Widget
Je crée un Border carré qui vas contenir la minimap, les images qui seront crées pour représenter les murs seront construits dans le widget et ensuite parentées à ce Border et repositionnées à un offset approprié.
Étape 2 - Collecte des références des murs
J'ajoute toutes les références de portes et de murs avec le tag "Wall" dans un array.
Étape 3 - Calculer les extrémités du niveau
Je compare ensuite les positions X et Y de tous les murs pour avoir les variables des extremités du niveau.
Étape 4 - Définir le centre et échelle du niveau
Les extrémités du niveau permettent alors de définir le centre et l'échelle du niveau l'aide de cette formule.
Étape 5 - Fonction d'affichag
Le array contenant les références aux murs du niveau est ensuite envoyé dans une fonction qui vas traité l'affichage de chaque mur selon leurs tags.
Étape 6 - Filtrer références selon Tag
À l'interieur de la fonction, une boucle foreach prend chaque référence du array et compare son tag pour l'envoyer dans une fonction qui construit une image selon la rotation, la longueur et l'Offset du mur en question. Ces paramètres dépendent du tag assigné au mur, j'aurrais tiré les murs selon leurs nom si Unreal prennait en compte le nom des objets lors d'un Build.
La forme du triage manque de simplicité. Il y a trop de "BRANCH" et "IF". J'étais nouveau avec Blueprint, donc je ne connaissais pas les nodes qui auraient rendu cela plus simple, comme "Sequencer". Maintenant, au lieu d'utiliser des tags, j'aurais utilisé un tableau d'Enum qui m'aurait permis de traiter toute l'information en une ligne, sans avoir à utiliser une douzaine de "Branch".
Étape 7 - Attribuer paramètres selon tag
Chaque référence de mur est envoyée à une fonction qui va afficher un trait sur la minimap à la dimension et à la rotation du mur.
Les murs du niveau varient en longueur, orientation et formes ; certains sont diagonaux et d'autres forment des coins. J'ai donc dû leur appliquer des tags pour que le blueprint puisse les distinguer. Les tags sont appliqués automatiquement par un script qui lie les noms des assets et applique un tag selon les références indiquées dans le nom.
J'envoie les informations de la référence du mur à une fonction qui va enfin l'afficher sur le widget.
Étape 8 - Breakdown les Variables
Voilà la façon dont les propriétés d'un mur sont passés à la fonction qui l'affichera sur le widget. Je prend la position du mur et l'ajoute à son offset, je fait de même pour sa rotation puis je multiplie sa longuer par son échelle (les assets de murs diffèrent en longuer mais leurs scale affichent toujours "1" donc je prend la taille de base de 400 et je la multiplie par 0.5 (World Scale) s'il s'agit d'un mur d'une longueur de 200 par exemple).
J'ajoute ensuite le deuxième tag du mur, le deuxième tag indique si le mur appartient à une salle contenant une caméra (lorsqu'une camera de sécurité est sélectionnée, les murs de la salle deviennent jaune sur la minimap, pour que ça marche, j'ai fait en sorte que lorsqu'un mur est dans le collider volume d'une salle, la salle applique un tag à son nom sur ce mur, lorsque l'image de ce mur serra construite, selon son tag, on ajoutera cette image au array d'images référencés par la salle lorsqu'elle s'allume).
Étape 9 - Construire image dans nouvelles coordonnées
Dans la fonction qui crée les images, je construit une image dans le widget et je passe la position du mur par une formule qui adapte la position du mur dans le niveau en décalage proportionnel au Widget, ce vector de décalage en pixel est ensuite approprié au "Render Translation" de l'image.
Étape 10 - Formule pour traduire coordonnées
Voilà la formule par laquel j'ai fait passé la position du mur dans le niveau pour en faire un vecteur de position proportionnel au Border de mon widget.
Étape 11 - Élargir l'image à l'échelle du mur
Maintenant pour faire en sorte que la longueur de l'image soit proportionnel à la longueur du mur qu'elle représente, je la passe par une autre fontion formule qui adapte la longueur d'unité du mur (qui varie généralement de 50 à 400 unités) en longueur d'image approprié pour l'échelle de la map sur le Border.
Étape 12 - Formule de mise à échelle
Voilà à quoi ressemble la formule. Le "Scale" est la variable qu'on a définit à l'étape 4 et le multiplicateur 1240 a été trouvé en éssait erreur.
Pour le trouver, j'ai juste mit deux murs de même longueur à côté de l'autre dans un niveaux vide et j'ai augmenté la valeur de ce multiplicateur jusqu'à ce que je vois dans la minimap généré que les deux murs se touchent comme ils le font dans le niveau, avec ça, j'étais sure que le multiplicateur mettait bien les images de murs à échelle.
Étape 13 - Répéter le processus pour les caméras de surveillance
Ensuite j'e fait la même chose que j'ai fait pour les murs mais pour les bouttons de caméra. Je détecte les salles avec des caméra dans le niveau puis dans un foreach,
je construit un custom widget button pour eux.
Étape 14 - Créer Bouttons Widget
Voilà à quoi le tout ressemble, assez similaire à la création des murs, c'est juste que dans le cas des bouttons, ce sont des custom widget que j'ai créée et dans lesquels il y a un blueprint qui indique le ce que le boutton doit faire lorsqu'il est sélectionné. En somme, ils affichent le "Feed" de leurs caméra de surveillance lorsqu'ils sont sélectionnés.
Runner Gunner est un mini-projet Unity sur lequel j'ai travaillé pendant 9 semaines. C'est un roguelike procédural dans lequel le joueur progresse d'une salle à l'autre pour combattre des vagues d'ennemis et récupérer des armes.
Mes tâches
- Programmation d'un système de génération dynamique de salles et de couloirs
- Intégration d'un inventaire 'scalable' qui prend en charge un système d'armes réalisé avec des Scriptable Objects.
- Animation manuelle des personnages avec des 'animation layers'.
- Intégration des mécaniques de combat, des ennemis et des effets de particules.
L'ensemble a été conçu pour être 'scalable'. L'ajout d'une nouvelle arme est réalisé avec des objets scriptables, facilitant ainsi l'intégration de nouvelles armes. Les animations sont réalisées manuellement, et pour ce projet, j'ai appris à utiliser les 'Animation Layers' de Unity.
Section 2 - Salles Procédurals
Pour la première étape du donjon procédural, j'ai dû programmer des salles de dimensions aléatoires. C'était ma première expérience avec la génération procédurale, mais après quelques recherches, j'ai compris que la matière de base incorporait beaucoup de méthodes qui m'étaient familières. Mes salles procédurales sont donc simples, mais j'ai pu ajouter de nombreuses fonctionnalités à leur script pour les rendre polyvalentes.
En bref, le script crée des rangées de tuiles avec des boucles "for loop" qui les étendent en largeur et en profondeur. Les variables qui déterminent ces dimensions sont aléatoires et peuvent également être ajustées. À partir de cette fondation, j'ai pu ajouter des variables qui déterminent le nombre maximum d'ennemis qui peuvent apparaître dans la salle, ainsi que le nombre maximum de sorties qui peuvent être générées. Il y a bien sûr aussi un nombre minimum de sorties qui dépend de la dimension de la salle.
Section 3 - Corridors
Défis
Les couloirs fonctionnent comme les salles : une fois que le joueur entre dans un couloir, une salle est générée au bout de ce dernier. Cependant, cela ne prenait pas en compte le problème selon lequel si un couloir pointait vers une autre salle du donjon, le couloir générerait une autre salle par-dessus cette dernière. Les murs et portes des deux partageraient le même espace, ce qui brisait le système du donjon.
Solution
La première façon de gérer ce problème était de donner une capacité aux couloirs de détecter si une salle était en face d'eux. Pour ce faire, j'ai fait en sorte que lorsque le joueur ouvre une porte pour générer un couloir, un raycast est projeté de la porte dans la direction du couloir. Si ce raycast touche la structure d'une autre salle, le couloir va alors relier la salle précédente à la salle qui a été touchée par le raycast. Pour cela, il ne fait que remplacer le mur touché par une porte de sortie.
Cela règle une partie du problème, mais il fallait aussi penser à ce qui se passerait si une salle n'était pas directement devant une porte mais était quelques unités à gauche ou à droite. Dans ce scénario, le couloir généré ne toucherait pas à un mur, mais la salle qui serait créée à l'extrémité pourrait entrer en conflit avec la salle précédente qui serait à gauche ou à droite. La solution à ce problème serait alors de projeter des raycasts à gauche et à droite du premier. Lorsque ces raycasts touchent des salles, ils retournent l'information des unités occupées, ce qui pourrait déterminer les limites de dimensions pour la salle qui sera créée à côté de ces coordonnées.
Section 4 - Room Manager
Jusque là le dongeon ne faisait que généré des salles et coulouirs à dimension aléatoir, mais j'avais besoin d'injecter une structure de progression au niveau. Je voulais qu'apprès avoir visité un certain nombre de salle, le joueur soit confronté à certains évenements ou récompenser avec de nouvelles armes.
J'ai alors ajouter un script room Manager qui prend en compte le nombre de salles qui ont été visités par le joueur pour que la prochaine salle généré après un certain moment du niveau soit une des salles pré-construites assigné dans les prefabs du script. Comme ça, j'ai pu décider qu'après un certains nombre de visites, le joueur entrerait dans la salle de boss ou de récompense.
Section 5 - NavMesh Dynamique
Un autre problème que j'ai rencontré durant l'intégration du donjon était l'application d'un navmesh dynamique. Jusqu'à présent, ajouter des ennemis et une IA était simple, car je n'avais qu'à générer un navmesh avant de lancer le jeu pour les faire bouger. Cependant, vu que le donjon est aléatoire et que le joueur ajoute une salle au niveau à chaque fois qu'il progresse, je ne pouvais pas générer mon navmesh à l'avance.
J'ai donc dû me renseigner sur la manière de générer un navmesh pendant l'exécution de Unity. J'ai rapidement découvert que cela n'était pas possible sans plugin, alors j'en ai trouvé un qui permet d'entrer des commandes dans les scripts affectant le navmesh.
Section 6 - Défis murs invisibles
Un des défis que j'ai dû adresser avec des mathématiques était lié aux murs du niveau. L'angle de vue du jeu fait que lorsque le joueur se colle au bas d'une salle, les murs de ce côté cachent le joueur à la caméra.
Une solution que j'ai envisagée était d'ajouter un shader qui révèle le joueur à travers les murs, comme dans d'autres roguelikes. Cependant, se contenter de révéler le joueur et les ennemis ne suffisait pas. Dans chaque salle, la moitié des murs du côté de la caméra couvre toujours une partie du sol, ce qui encombre la visibilité du niveau. Dans d'autres jeux avec le même angle de vue, ils éliminent les murs du côté de la caméra. C'est donc la solution que j'ai décidé de mettre en œuvre.
Solution murs invisibles
Éliminer les murs inférieurs d'une salle serait plus facile si mon niveau était déjà construit, mais vu qu'il est généré aléatoirement, j'ai dû indiquer avec un script quels murs seraient rendus invisibles et quand ils seraient désactivés. Dans le contexte de mon jeu, les murs du côté inférieur de la salle que le joueur visite devraient être invisibles car ils sont toujours entre lui et la caméra.
Pour ce faire, j'ai dû trouver un point commun qui sépare les murs du côté inférieur des murs du côté supérieur. Ma première pensée était que leur position les démarquait, mais le problème avec cela était que, pour les salles rectangulaires ou étendues, certains murs du côté supérieur étaient plus proches de la caméra que ceux qui étaient du côté inférieur.
En revanche, j'ai pu les démarquer par leurs rotations. Chaque mur est identique, mais ils sont tous orientés selon le côté de la salle auquel ils appartiennent. J'ai donc ajouté une fonction au script de génération de donjon qui ajoute tous les murs des deux côtés inférieurs d'une salle à une liste. Les objets de cette liste ont leur MeshRenderer désactivé lorsque le joueur entre dans la salle.
C'était plus compliqué que prévu car les salles peuvent être générées dans différentes positions et rotations, ce qui multipliait les unités de rotation des murs générés. Ainsi, si je voulais rendre tous les murs orientés à 90 degrés invisibles, je devais prendre en compte ceux qui avaient la même orientation mais une rotation de 460 degrés ou -270 degrés. Il n'y avait pas de limite au nombre de fois que l'orientation des salles ajoutait 360 degrés de rotation à ces murs, donc j'ai dû utiliser des formules pour déterminer la vraie valeur de l'orientation de chaque mur.
Section 7 - Weapon system
C'était la première fois que j'intégrais un système d'arme, mais j'ai bien fait de m'assurer que la fondation de ces mécaniques était scalable. Le joueur dispose de 4 emplacements d'inventaire dans lesquels il peut équiper une arme qu'il trouve. Chaque arme a plusieurs variables qui les démarquent, comme le nombre de projectiles qu'elles tirent par coup, leurs effets de particules, leur temps de recharge, et la classe d'arme à laquelle elles appartiennent. Cette classe influence également l'animation du personnage lorsqu'il équipe cette arme.
Bref, Chaque arme est différente, donc j'ai décidé, pour faciliter l'intégration de futures armes, d'en faire des Scriptable Objects. De cette façon, ajouter une nouvelle arme au jeu ne demande que de modifier les variables du Scriptable Object et de le renommer, ce qui est vraiment pratique.
Le système d'inventaire est plus simple à cause de cela aussi. Lorsque le joueur ramasse un objet, le script transmet l'information du Scriptable Object à un emplacement de l'inventaire. Lorsque le joueur équipe l'objet, les fonctions du script universel "Gun" sont appelées et fonctionnent selon les variables du Scriptable Object.
Section 8 - Animation
Pour l'animation des personnages, j'étais limité par le temps et mon manque de connaissance en modélisation et rig d'animation. J'ai donc modelé des personnages simples et faciles à animer, car ils n'ont pas besoin de rig pour être animés. Chaque membre du personnage est un objet séparé du reste, et ils sont parentés ensemble en hiérarchie. De cette manière, j'ai pu créer mes propres animations simplement manuellement avec l'Animator de Unity.
J'ai dû expérimenter avec les Animation Layers de Unity pour superposer les animations d'armes à feu avec les cycles de marche.