top of page

APART

Equipe

Durée projet

Rôles

Moteur

Plateforme

8 personnes

8 mois

Unity

PC

Programmeuse gameplay,

Artiste 2D

Apart est le jeu sur lequel je travaille actuellement dans le cadre de ma fin d’études à l’ESMA.

Il s’agit d’un jeu d’exploration et de contemplation où le joueur incarne un jeune berger effectuant sa première transhumance avec son chien et son troupeau de moutons.

 

Sur ce projet, je suis responsable d’une partie de la programmation gameplay, du système de caméra mais également du concept art.

APART_Affiche.png

Affiche du jeu

capture1.png
capture.png

Captures in-game

------------------------

Caméra

 

Le premier point que je souhaiterais détailler sur ce projet est le système de caméra.

En effet, le but étant de créer une expérience contemplative, la caméra est un élément central de notre jeu.

Il nous fallait une caméra très discrète mais également suffisamment autonome afin de pouvoir accompagner le joueur dans son exploration sans le gêner.

Une de mes principales inspirations pour ce système est la caméra de Journey (ThatGameCompany), notamment pour sa mise en valeur de l'environnement et sa gestion des obstacles.

Toutefois, contrairement à Journey, notre jeu comporte plusieurs protagonistes : le berger, les moutons et le chien. Il m'a donc fallut adapter les point de focus de la caméra en fonction des situations et de nos besoins.

Le jeu étant développé sur Unity, j'ai décidé d'utiliser les outils Cinemachine disponibles afin de mettre en place une caméra FreeLook, c'est-à-dire libre autour du personnage, paramétrable sur 3 niveaux.

Afin de "smoother" les transitions de hauteur de caméra, j'ai mis en place un simple script modifiant la vitesse de déplacement sur l'axe Y en fonction de cette hauteur. Ainsi, le changement de distance semble plus dynamique et plus réactif.

camera_freelook.gif

Déplacements de la caméra tout autour du personnage

Le second élément est probablement le plus important de part son étroite liaison avec notre gameplay.

Il s'agit d'intégrer les moutons autant que possible aux plans de caméra.

En effet, comme le but de notre jeu est de guider avec succès le troupeau à travers la montagne, le joueur doit pouvoir à la fois garder vue sur son personnage mais aussi sur ses moutons.

Pour cela, j'ai utilisé le TragetGroup de Cinemachine en venant y apporter certaines modifications via script.

J'update le poids du troupeau en fonction de la direction dans laquelle regarde la caméra. Par exemple, si la camera regarde dans la direction générale du troupeau, son poids augmentera. En revanche, si la caméra tourne le dos au troupeau, le poids de ce dernier sera nul pour ne pas gêner. 

Comme le poids du berger reste constant, le cadrage du plan s'adapte donc dynamiquement.

camera_targetGroup.gif

Update du weight du troupeau en fonction de la direction de la caméra

Un autre élément particulièrement important d'un système de caméra est sa gestion des collisions et des obstacles.

En ce qui concerne les collisions, le component Cinemachine Collider est utilisé pour gérer les collisions avec les limites invisibles du niveau. Toutefois, les collisions avec le terrain sont gérées par un système custom à base de raycast tiré vers le sol.

Enfin, notre niveau comporte un certains nombre d'obstacles derrière lesquels le berger pourrait disparaître et qui pourraient gêner la vue. J'ai donc mis en place un système d'anticipation d'obstacles.

schémas_raycast-cam.png

Raycasts tirés depuis la caméra vers les côtés du berger

Pour cela, 4 raycasts sont lancés de chaque côté de l'avatar, en partant de la caméra vers le berger, pivotant à chaque fois de 5°, comme sur le schéma ci-contre.

Ainsi, il est possible de détecter un obstacle sur un côté du personnage.

Si ce dernier se dirige vers cet obstacle, la caméra peut anticiper ce mouvement en venant tourner d'elle-même pour éviter que le berger ne disparaisse derrière.

camera_onstacle.gif

Anticipation d'obstacle et transparence de l'objet quand disparition - sans input sur la caméra

Afin de compléter ce système, si le berger disparaît tout de même derrière un objet, comme un arbre par exemple, ce dernier vient changer momentanément de matériau afin de pouvoir passer en transparence.

------------------------

Flowfields

J'aimerais maintenant développer le système de flowfield mis en place pour le déplacement des IAs (les moutons et le chien) dans certains cas particuliers.

En effet, nos personnages autres que le berger se déplacent grâce à un navmesh. On leur donne une destination et les positions intermédiaires sont calculées automatiquement.

Cependant, dans certaines situations, nous avions besoin d'influencer les personnages à suivre un mouvement particulier.

 

Un exemple parlant est celui du passage de barrières.

Lorsque les moutons arrivent suffisamment proches d’un portail, ils sont “attirés” par ce dernier. Ce système permet d’assister le joueur dans sa manipulation du troupeau.

Flowfield_gif.gif

Troupeau suivant le flowfield sous ses pieds

Dans un premier temps, une grille de gameobjects positionnés à intervalles réguliers est créée afin de déterminer la zone d’influence. Le forward de chaque gameobject correspond au vecteur directionnel qu’il renverra.

grid_apart.gif

(La sprite de flèche n'est utilisée que pour le debug)

Ensuite, j’ai créé un script afin de gérer tous les vecteurs de la grille.

A l’initialisation, le script parcourt chaque objet, récupère sa position arrondie à l’entier inférieur ainsi que le vecteur directionnel associé et stocke ces informations dans un dictionnaire.

 

Afin de faciliter la comparaison de position entre un mouton et une case de la grid de flowfield, toutes les positions sont converties en Vecteur2Int.

En effet, notre terrain étant particulièrement vallonné et n’ayant pas plusieurs niveaux superposés, la valeur en Y des positions est ignorée. Les valeurs X et Z sont donc stockées dans un Vecteur2 dont les valeurs sont arrondies à l’entier inférieur.

Ainsi, si les vecteurs arrondis sont les mêmes, le mouton est bien sur la case, quelle que soit sa position exacte sur cette dernière.

 

Il existe plusieurs contextes dans lesquels les IA doivent suivre un flowfield.

  • une zone localisée liée au terrain (portail, topologie…)

  • un mouvement lié aux ordres du joueur qui peut se déclencher n’importe où (chien qui suit le troupeau, arrêt des moutons…)

fence_gif.gif

Flowfield de barrière

L’activation du flowfield peut être provoquée par l’entrée dans un collider (zone localisée) mais également par le changement de state de la StateMachine.

 

Dans les deux cas, lorsque l’IA commence à suivre un flowfield elle va chercher sa position, arrondie au dessous et convertie en Vecteur2Int, dans le dictionnaire de la grid, récupérer le vecteur direction associé et updater la destination du personnage sur le navmesh.

------------------------

Concept Art

Enfin, en ce qui concerne les tâches autres que la programmation sur lesquelles je travaille, j’ai réalisé un certain nombre de concepts arts pour le projet dans le cadre de la préproduction.


En effet, lorsque le projet était encore à l’état de concept, il fallait donner des visuels pour l’ambiance générale du jeu mais également pour les artistes 3D afin de définir précisément la DA.

C’est pour cela que j’ai réalisé différentes planches de concept pour les assets d’environnement mais également les personnages du berger et du chien.

J'ai également eu l'occasion de réaliser l'affiche pour notre jeu.

Quelques dessins que j'ai pu réaliser pour le projet

bottom of page