Unity - Roguelike 2D

Contrôleur d'animation des ennemis

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Le projet présenté dans cette série est tout aussi bien compatible avec Unity 4.6 qu'avec Unity 5.
Vous pouvez retrouver les autres épisodes de cette série dans le sommaire dédié.

II. Vidéo


Unity - Roguelike 2D - Contrôleur d'animation des ennemis


III. Résumé

Dans ce chapitre, le contrôleur d'animation des ennemis est défini. De plus, le code du script GameManager.cs est complété pour gérer les nouvelles fonctionnalités vues dans les chapitres précédents.

III-A. Contrôleur d'animation

Ouvrez le contrôleur d'animation « Enemy1 ».
Nous créons des transitions pour passer de l'animation par défaut « Enemy1Idle » à l'animation d'attaque « Enemy1Attack ». La transition est déclenchée à l'aide d'une variable déclencheur (trigger) appelée « enemyAttack ».
« Has Exit Time » est décochée et la durée de transition est mise à zéro. Pour la transition inverse, le temps de sortie est mis à 1 et la durée de transition à zéro.

La configuration de l'animation est très proche de celle vue pour le joueur.

III-B. GameManager.cs

III-B-1. Fonctionnalités

Nous ajoutons de nouvelles fonctionnalités au script :

  • turnDelay est une variable paramétrant l'attente entre deux tours du joueur ;
  • une liste d'ennemis pour pouvoir les déplacer à chaque tour ;
  • la fonction MoveEnemies() permettant de déplacer chaque ennemi séquentiellement ;
  • la fonction AddEnemyToList() permettant aux ennemis de s'enregistrer dans le GameManager.

III-B-2. Script

 
Sélectionnez
using UnityEngine;
using System.Collections;

namespace Completed
{
    using System.Collections.Generic;       // Nous permet d'utiliser les listes. 
    
    public class GameManager : MonoBehaviour
    {
        public float levelStartDelay = 2f;                      // Temps à attendre avant le début d'un niveau, en secondes.
        public float turnDelay = 0.1f;                          // Attente entre chaque tour du joueur.
        public int playerFoodPoints = 100;                      // Valeur de départ pour les points de nourriture du joueur.
        public static GameManager instance = null;              // Instance statique de GameManager qui permet d'y accéder par les autres scripts.
        [HideInInspector] public bool playersTurn = true;       // Booléen pour vérifier si c'est le tour du joueur, public mais caché dans l'inspecteur.
        
        
        private BoardManager boardScript;                       // Contient une référence vers notre BoardManager qui définira le niveau.
        private int level = 1;                                  // Niveau actuel, affiché dans le jeu comme "Day 1".
        private List<Enemy> enemies;                          // Liste des ennemis, utilisée pour effectuer les commandes de déplacement.
        private bool enemiesMoving;                             // Booléen pour vérifier si les ennemis se déplacent.
        private bool doingSetup = true;                         // Booléen pour vérifier si nous configurons le niveau pour empêcher au joueur de se déplacer pendant ce temps.
        
        
        
        // Awake est toujours appelé avant les fonctions Start
        void Awake()
        {
            // Vérifie si l'instance existe déjà
            if (instance == null)
                
                // Si ce n'est pas le cas, définit l'instance à celle-ci
                instance = this;
            
            // Si l'instance existe déjà et que ce n'est pas celle-ci :
            else if (instance != this)
                
                // Alors détruit celle-ci. Cela applique le pattern Singleton, signifiant que nous ne pouvons avoir qu'une et seulement une instance de GameManager.
                Destroy(gameObject);    
            
            // Définit cette instance pour ne pas être détruite au rechargement de la scène.
            DontDestroyOnLoad(gameObject);
            
            // Assigne une nouvelle liste d'ennemis à la variable enemies.
            enemies = new List<Enemy>();
            
            // Récupére une référence du script BoardManager attaché.
            boardScript = GetComponent<BoardManager>();
            
            // Appelle la fonction InitGame pour initialiser le premier niveau.
            InitGame();
        }
        
        // Appelé chaque fois qu'une scène est chargée.
        void OnLevelWasLoaded(int index)
        {
            // Ajoute un à notre compteur de niveau.
            level++;
            // Appelle la fonction InitGame pour initialiser le niveau.
            InitGame();
        }
        
        // Initialise le jeu pour chaque niveau.
        void InitGame()
        {
            // Pendant l'initialisation, le joueur ne peut pas se déplacer.
            doingSetup = true;
            
            // Enlève tous les ennemis de notre liste pour être prêt pour le prochain niveau.
            enemies.Clear();
            
            // Appelle la fonction SetupScene du script BoardManager, en lui passant le numéro du niveau.
            boardScript.SetupScene(level);
            
        }
        
        
        // Update est appelé à chaque image.
        void Update()
        {
            // Vérifie si playersTurn ou enemiesMoving ou doingSetup sont à true.
            if(playersTurn || enemiesMoving || doingSetup)
                
                // Si l'un d'entre eux est à true, retourne et n'appelle pas la fonction MoveEnemies.
                return;
            
            // Commence le déplacement des ennemis.
            StartCoroutine (MoveEnemies ());
        }
        
        // Appelle cette fonction pour ajouter l'ennemi en paramètre à la liste des ennemis.
        public void AddEnemyToList(Enemy script)
        {
            // Ajoute un ennemi à la liste des ennemis.
            enemies.Add(script);
        }
        
        
        // La fonction GameOver est appelée lorsque le joueur obtient un nombre de points de nourriture à 0.
        public void GameOver()
        {
            
            // Active le GameObject d'image à fond noir.
            levelImage.SetActive(true);
            
            // Désactive ce GameManager.
            enabled = false;
        }
        
        // Coroutine pour déplacer les ennemis en séquence.
        IEnumerator MoveEnemies()
        {
            // Tant que enemiesMoving est à true, le joueur ne peut pas se déplacer.
            enemiesMoving = true;
            
            // Attend turnDelay secondes, qui est par défaut à .1 (100 ms).
            yield return new WaitForSeconds(turnDelay);
            
            // S'il n'y a aucun ennemi (dans le premier niveau):
            if (enemies.Count == 0) 
            {
                // Attend turnDelay secondes entre les déplacements.
                yield return new WaitForSeconds(turnDelay);
            }
            
            // Boucle sur la liste des ennemis.
            for (int i = 0; i < enemies.Count; i++)
            {
                // Appelle la fonction MoveEnemy pour l'élément i de la liste d'ennemis.
                enemies[i].MoveEnemy ();
                
                // Attend moveTime avant de déplacer le prochain ennemi.
                yield return new WaitForSeconds(enemies[i].moveTime);
            }
            // Une fois que les ennemis ont fini de se déplacer, remet playersTurn à true afin de permettre au joueur de se déplacer.
            playersTurn = true;
            
            // Les ennemis se sont déplacés, définit enemiesMoving à false.
            enemiesMoving = false;
        }
    }
}

III-C. Enemy.cs

Le script des ennemis doit aussi être mis à jour.

III-C-1. Fonctionnalités

La classe Enemy doit s'inscrire dans la liste en utilisant l'instance du GameManager :

 
Sélectionnez
GameManager.instance.AddEnemyToList(this);

Lorsque l'ennemi attaque, celui-ci doit mettre à true la variable « enemyAttack » configurée dans le contrôleur d'animation.

 
Sélectionnez
animator.SetTrigger("enemyAttack");

III-C-2. Éditeur

Maintenant que le script est prêt, nous pouvons l'ajouter aux préfabriqués « Enemy1 » et « Enemy2 ». Le « BlockingLayer » doit être défini à « BlockingLayer ».
Ensuite, les dégâts infligés au joueur par chaque ennemi sont définis séparément.

IV. Ressources

Vous pouvez télécharger les ressources pour ce projet sur l'Asset Store de Unity.

V. Commenter

Vous pouvez commenter et donner vos avis dans la discussion associée sur le forum.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2015 Unity Technologies. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.