Aller au contenu

Cours 9

Tranche verticale

Phase de test des jeux en classe. (Ne pas expliquer son jeu)

  1. Sur GitHub, ouvrir le repo de votre jeu
  2. Créer un fichier tranche-verticale.md (Add file > Create new file)
  3. Cliquer sur Commit changes...
  4. Cliquer sur tranche-verticale.md
  5. Cliquer sur le petit crayon en haut à droite et laisser la page ouverte
  6. Ouvrir son jeu dans Unity
  7. Régler le bon niveau sonore du jeu

  1. Changer de poste et démarrer le jeu
  2. Lorsque vous avez terminé, faire Stop dans Unity
  3. Ouvrir la page du fichier tranche-verticale.md et écrire 2 rétroactions :
    • Ce que vous avez aimé
    • Ce qui doit être amélioré

Sujets d'analyse

Environnement, HUD, Affordance, Éclairage, Prérequis, Audio, Créativité

Divers

Activer ou désactiver le tir du « Character Controller »

  1. Sur le PlayerArmature ou PlayerCapsule, décocher le tir dans l'Inspector
  2. Sur un CES, ajouter une action Invoke Events
    • Objet = PlayerArmature ou PlayerCapsule
    • Fonction = Tir, puis bool enabled
    • Cocher la case pour l'activer
Le « Character Controller » bloque la souris, et ce, à travers toutes les scènes

Le script suivant vous permet, au chargement de la scène ou via une Action CES, d'activer ou désactiver la souris.

  1. Dans la Hierarchy : clic-droit Create Empty
  2. Appliquer ce script sur l'objet :
MouseLock.cs
using UnityEngine;

public class MouseLock : MonoBehaviour
{
   public bool locked = false;

   void Start()
   {
       SetLocked(locked);
   }

   public void SetLocked(bool value)
   {
       locked = value;
       Cursor.lockState = locked ? CursorLockMode.Locked : CursorLockMode.None;
       Cursor.visible = !locked;
   }
}
Déclencher une action, avant, pendant ou après une animation

Utiliser un Animation Event.

  1. Placer le script suivant sur le GameObject animé

    AnimationEventRelay.cs
    using UnityEngine;
    using UnityEngine.Events;
    
    public class AnimationEventRelay : MonoBehaviour
    {
       public UnityEvent onAnimationEvent;
    
       public void Trigger()
       {
           onAnimationEvent.Invoke();
       }
    }
    
  2. Dans le panneau Animation, placer le curseur au moment où déclencher l'événement

  3. Cliquer sur l'icône Add Event
  4. Dans l'Inspector, dans Function, choisir AnimationEventRelay > Methods > Trigger ()

PNJ

Le personnage non-joueur (PNJ ou NPC) se décrit selon deux axes :

Déplacement

  • Statique (idle) : reste en place, animé ou non
  • Errance (wander) : se déplace au hasard dans une zone, avec des pauses
  • Patrouille (patrol) : suit un trajet défini par des points de passage
  • Poursuite (follow) : se déplace vers une cible
  • Fuite (flee) : s'éloigne d'une cible

Rôle

  • Décor : anime le monde, aucune interaction
  • Interactif non hostile : guide, marchand, dialogue
  • Hostile : menace le joueur et peut provoquer un échec

Un PNJ combine donc un mode de déplacement et un rôle.

PNJ en attente (idle)

Un PNJ en attente reste en place. Il peut être animé ou pas.

Animer un PNJ en attente

Mixamo est un service gratuit d'Adobe qui offre une banque de plusieurs animations d'humanoïdes.

Ça tombe bien, les personnages Synty sont humanoïdes et ont déjà un squelette prêt à être animé. C'est ce que nous exploiterons.

Télécharger l'animation

  1. Aller sur mixamo.com et se connecter avec votre compte Adobe
  2. Cliquer sur Upload Character et choisir un personnage Polygon en format FBX (ex. : Models/Characters.fbx)
  3. Choisir une animation sur mixamo.com
  4. Cliquer sur Download, régler les champs ci-dessous, puis cliquer sur Download :
Champ Valeur
Frames per Second 60
Pose (si affiché) Original Pose
Skin (si affiché) Without Skin

Plusieurs personnages superposés 🤨

Le fichier Characters.fbx d'un pack Synty contient tous les personnages du pack sur un seul squelette. Dans Mixamo, ils apparaissent superposés : c'est normal. Avec Without Skin, aucun de ces maillages ne se retrouve dans le fichier téléchargé.

Configurer le rig

  1. Glisser le FBX téléchargé dans 📁 Assets > 📁 _ > 📁 Animations
  2. Dans l'Inspector, onglet Rig : Animation Type = Humanoid, puis Apply
  3. Avatar Definition = Copy From Other Avatar
    • Source = CharactersAvatar (ex. : 📁 SyntyStudios > 📁 PolygonCity > 📁 Models > Characters > CharactersAvatar)

Configurer le clip

  1. Dans l'Inspector, onglet Animation
  2. Renommer le clip (ex. : Idle; par défaut, c'est mixamo.com). C'est le champ à droite du triangle turquoise
  3. Pour boucler l'animation, cocher Loop Time
  4. Cocher Bake Into Pose dans les trois sections Root Transform (Rotation, Position Y, Position XZ)
  5. Cliquer sur Apply

Certaines animations se configurent différemment

Certaines animations sont faites pour ne jouer qu'une seule fois. Dans ce cas, laisser Loop Time décoché.

D'autres, comme la marche, déplacent le personnage. Pour laisser Unity s'en charger, il faut donc décocher Bake Into Pose dans Root Transform Position (XZ).

Code des couleurs : 🟢 = boucle propre, 🟡 = léger décalage, 🔴 = saut visible.

Créer l'Animator

  1. Dans 📁 Assets > 📁 _ > 📁 Animations : clic-droit Create > Animation > Animator Controller
  2. Clic-droit sur l'Animator Controller > Rename, le nommer AC_NPC
  3. Double-cliquer sur AC_NPC pour ouvrir le panneau Animator
  4. Clic-droit dans la grille, Create State > Empty
  5. Sélectionner New State puis, dans l'Inspector, le renommer (ex. : Idle) et choisir le clip dans le champ Motion

Appliquer l'animation sur un PNJ

  1. Sélectionner le personnage dans la Hierarchy. Dans son composant Animator :
    • Controller = le controller créé (AC_NPC)
    • Avatar = laisser l'avatar par défaut du personnage Synty
    • Apply Root Motion = décoché

PNJ en errance (wander)

Un PNJ en errance se déplace au hasard dans une zone, avec des pauses.

Animer un PNJ en errance

Préparer le terrain

Il faut d'abord créer une zone marchable avec un NavMesh.

  1. Installer le package AI Navigation : Window > Package Manager > Unity Registry > AI Navigation > Install
  2. Dans la Hierarchy : clic-droit Create Empty, le nommer NavMesh
  3. Add Component > NavMesh Surface
  4. Cliquer sur Bake : la zone marchable apparaît en bleu dans la Scene

    Zone spécifique, plutôt que générale

    Sur le NavMesh Surface, Object Collection > Collect Objects = Volume. Un cube s'affiche : c'est la zone marchable.

    Exclure une partie du navmesh

    1. Dans la Hierarchy : clic-droit Create Empty, le nommer NavMesh Modifier
    2. Add Component > NavMesh Modifier Volume
    3. Sur le NavMesh Surface, changer Default Area à Marchable (créer si absent)
    4. Sur le NavMesh Modifier Volume, changer Area Type à Non marchable (créer si absent)
    5. Sur le NavMesh Surface, cliquer sur Bake

Il faut ensuite placer le PNJ sur la zone marchable. Celui-ci deviendra ce qu'on appelle un agent.

  1. Sélectionner le PNJ, puis Add Component > Nav Mesh Agent
  2. Placer le PNJ sur une zone bleue du NavMesh

    Base offset

    Si le PNJ flotte ou s'enfonce dans le sol, vous pouvez ajuster le champ Base Offset sous Nav Mesh Agent.

Déplacement aléatoire

L'errance d'un PNJ repose sur le concept de destinations (waypoint) générées aléatoirement. Cette opération se fait en code.

  1. Ajouter le script NPCWander.cs dans 📁 Assets > 📁 _ > 📁 Scripts
  2. Glisser le script NPCWander.cs sur le PNJ

Pour certains jeux, ça peut convenir et on pourrait s'arrêter là. Toutefois, il ne serait pas étonnant de trouver qu'il manque une animation de marche dans l'équation.

Pour ce faire, il faudrait donc changer d'animation en fonction de l'état du PNJ. C'est ce qui s'appelle une machine à états, ou state machine.

Nouvelle animation de marche

  1. Aller sur mixamo.com et télécharger une animation de marche
  2. Configurer son rig
  3. Configurer son clip
    • Renommer le clip (ex. : Marche; par défaut, c'est mixamo.com)
    • Cocher Loop Time, puis Bake Into Pose dans Root Transform Rotation et Root Transform Position (Y)
    • Garder Bake Into Pose décoché dans Root Transform Position (XZ) : ce sera géré par le script de déplacement

Configurer la machine à états

  1. Double-cliquer sur AC_NPC pour l'ouvrir dans le panneau Animator
  2. Onglet Parameters du panneau Animator : + > Bool, le nommer walking
  3. Clic-droit dans la grille, Create State > Empty
  4. Sélectionner New State puis, dans l'Inspector, le renommer (ex. : Walk) et choisir le clip de marche dans le champ Motion
  5. Clic-droit sur Idle > Make Transition vers Walk, puis de Walk vers Idle
  6. Cliquer sur chaque transition (petite flèche blanche) et configurer pour chacune :

    Réglage Idle Walk Walk Idle
    Has Exit Time décoché décoché
    Conditions walking = true walking = false

Appliquer la machine à états au PNJ

  1. Dans la Hierarchy, cliquer sur le PNJ
  2. Dans l'Inspector, glisser le composant Animator vers le champ Animator sous NPC Wander (Script)

    Walk Parameter

    La valeur du champ Walk Parameter doit être identique au nom du paramètre dans le panneau Animator

PNJ en poursuite (follow)

Un PNJ en poursuite se déplace vers une cible (souvent le joueur) lorsque celle-ci entre dans sa zone de détection.

Déplacement du PNJ

La poursuite repose sur des zones de détection autour du PNJ. Cette opération se fait en code.

  1. Ajouter le script NPCFollowerEditor.cs dans 📁 Assets > 📁 _ > 📁 Scripts > 📁 Editor
  2. Ajouter le script NPCFollower.cs dans 📁 Assets > 📁 _ > 📁 Scripts
  3. Glisser le script NPCFollower.cs sur le PNJ
  4. Glisser PlayerArmature ou PlayerCapsule dans le champ Target
  5. Pour activer les animations, dans l'Inspector du PNJ, glisser le composant Animator vers le champ Animator sous NPC Follower (Script)

Nouvelle animation de course

Bien qu'il ne soit pas obligatoire d'ajouter une animation de course, celle-ci peut s'avérer plus cohérente et convaincante.

  1. Aller sur mixamo.com et télécharger une animation de course
  2. Configurer son rig
  3. Configurer son clip
    • Renommer le clip (ex. : Course; par défaut, c'est mixamo.com)
    • Cocher Loop Time, puis Bake Into Pose dans Root Transform Rotation et Root Transform Position (Y)
    • Garder Bake Into Pose décoché dans Root Transform Position (XZ) : ce sera géré par le script de déplacement

Configurer la machine à états

  1. Double-cliquer sur AC_NPC pour l'ouvrir dans le panneau Animator
  2. Onglet Parameters du panneau Animator : + > Bool, le nommer run
  3. Clic-droit dans la grille, Create State > Empty
  4. Sélectionner New State puis, dans l'Inspector, le renommer (ex. : Run) et choisir le clip de course dans le champ Motion
  5. Clic-droit sur Run > Make Transition vers Walk, puis de Walk vers Run
  6. Cliquer sur chaque transition (petite flèche blanche) et configurer pour chacune :

    Réglage Walk Run Run Walk
    Has Exit Time décoché décoché
    Conditions run = true run = false

Activer la course au PNJ en poursuite

  1. Sélectionner le PNJ dans la Hierarchy
  2. Dans l'Inspector, sous NPC Follower (Script), cocher Run When Chasing

Ça va activer la course quand le PNJ poursuit sa cible, mais la gestion d'errance reste là lorsque nécessaire.

À l'attaque ⚔

Quand le PNJ arrive près de sa cible, on peut s'imaginer qu'il veuille exécuter une action, par exemple, une attaque !

Une attaque corps à corps nécessite une technique qu'on appelle hitbox. C'est une zone de collision temporaire.

Nouvelle animation d'attaque 👊

  1. Sur mixamo.com , télécharger une animation de coup (ex. : Punch), avec les mêmes réglages que l'animation d'attente
  2. Configurer son rig
  3. Configurer son clip :
    • Renommer le clip Attack
    • Loop Time décoché : le coup ne joue qu'une fois
    • Bake Into Pose coché dans les trois sections Root Transform : le PNJ reste sur place pendant le coup

Configurer la machine à états

  1. Double-cliquer sur AC_NPC
  2. Onglet Parameters : + > Trigger, le nommer attack
  3. Créer un état nommé exactement Attack et choisir le clip d'attaque dans Motion

  4. Créer les transitions suivantes :

    Réglage Any State Attack Attack Idle
    Has Exit Time décoché coché
    Conditions attack (aucune)
    Can Transition To Self décoché —
  5. Sur le PNJ, dans NPC Follower :

    • Cocher Can Attack
    • Attack Trigger = attack (le même nom que le trigger)

Placer la hitbox

  1. Dans la Hierarchy, à l'intérieur du PNJ, ajouter un Trigger Cube
  2. Dans Collider Event :
    • Required Tags : Player
    • After Trigger = Do Nothing
    • Actions : l'effet du coup (ex. : Variable pour retirer une vie, Audio pour un son d'impact, etc.)
    • Actions, en dernier : Invoke Events, objet = le PNJ, fonction = NPCFollower > HitboxOff
Pour les puristes

Si vous tenez à ce que le poing (ou l'épée par exemple) soit le point de contact, vous pouvez placer le Trigger Cube comme enfant d'un membre (ex. : Hand_R).

Utiliser la hitbox dans l'animation !

  1. Dans le panneau Project, sélectionner le FBX de l'animation d'attaque
  2. Dans l'Inspector, onglet Animation, déplier la section Events
  3. Dans l'aperçu au bas de l'Inspector, avancer l'animation jusqu'au moment où l'attaque commence
  4. Cliquer sur Add Event et inscrire HitboxOn dans Function
  5. Avancer jusqu'au moment où l'attaque se termine
  6. Cliquer sur Add Event et inscrire HitboxOff dans Function
  7. Laisser vides les champs Float, Int, String et Object, puis cliquer sur Apply

Tester la fenêtre d'impact

Le Contact Radius de NPC Follower (Script) arrête le PNJ pour qu'il ne se superpose pas au joueur. Toutefois, ça peut créer une certaine distance qui empêche la collision d'attaque. Dans ce cas, soit diminuer le Contact Radius, soit agrandir le Trigger Cube d'attaque.

Tourelle

Une tourelle est un objet fixe qui tire des projectiles sur une cible.

  1. Ajouter le script Turret.cs dans 📁 Assets > 📁 _ > 📁 Scripts
  2. Dans la Hierarchy, cliquer sur le + et choisir Create Empty
  3. Le renommer Turret
  4. Clic-droit sur Turret et choisir Create Empty
  5. Le renommer ShootStart
  6. Dans Turret, ajouter un modèle (ex. : une tourelle)
  7. Glisser le script Turret.cs sur le GameObject Turret
  8. Glisser PlayerArmature ou PlayerCapsule dans le champ Target
  9. Glisser un prefab dans le champ Bullet Prefab
    ⚠ IMPORTANT : ce prefab doit avoir un Rigidbody
  10. Glisser ShootStart dans le champ Fire Starting Point

Trello

  • Semaine 1
  • Semaine 2
  • Semaine 3
  • Semaine 4
  • Semaine 5
  • Semaine 6
  • Semaine 7 | 🏃🏻‍♂️ Sprint 1 : Prototype
  • Semaine 8 | 22 octobre
  • Semaine 9 | 29 octobre 🏃🏻‍♂️ Sprint 2 : Tranche verticale 🗓️ Aujourd'hui
  • Semaine 10 | 5 novembre
  • Semaine 11 | 12 novembre
  • Semaine 12 | 19 novembre 🏃🏻‍♂️ Sprint 3 : Alpha
  • Semaine 13 | 26 novembre
  • Semaine 14 | 3 décembre 🏃🏻‍♂️ Sprint 4 : Beta
  • Semaine 15 | 10 décembre 🏃🏻‍♂️ Sprint 5 : Oral

Version alpha

Dans une version alpha, le jeu est structurellement jouable du début à la fin et les mécaniques de base sont implémentées.

Version beta

Dans une version beta, le jeu est complet. Le développement se concentre sur les bugs, l'optimisation et l'équilibrage du jeu.

Nouvelles cartes

  • Must Terminer la zone 1, le cas échéant
  • Must Habiller la zone 2
  • Must Éclairer la zone 2
  • Must Sonoriser la zone 2
  • Must Prérequis complet pour la zone 2
  • Must Habiller la zone 3
  • Must Éclairer la zone 3
  • Must Sonoriser la zone 3
  • Must Prérequis complet pour la zone 3
  • Must Monter la scène Crédits, accessible depuis le menu titre

PNJ

  • Could Préparer le NavMesh
  • Could Ajouter un ou plusieurs PNJ
  • Could Appliquer la ou les animations des PNJ
  • Could Configurer le comportement des PNJ