Unity - Roguelike 2D

Interface utilisateur et niveaux

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 - UI et niveaux


III. Résumé

Dans ce chapitre, nous ajoutons des éléments d'interface utilisateur.

III-A. Procédure

Pour avoir une interface utilisateur, vous devez créer un canevas (canvas) :

GameObject → UI → Canvas

Celui-ci contiendra tous les éléments de votre interface utilisateur. Nous utilisons une image qui sera le fond pour nos éléments d'interface utilisateur :

GameObject → UI → Image

Nous utilisons les ancres afin que l'image s'étale sur l'intégralité du canevas. La couleur est définie à « noir ». Finalement, renommez-la « LevelImage ».
Ensuite, nous avons besoin d'un objet texte (Text) :

GameObject → UI → Text

Celui-ci permet d'afficher le numéro du niveau en cours. Renommez-le « LevelText ». Ancrez-le au centre du canevas. La couleur du texte est « blanc ». La taille est de 32. Le texte peut dépasser des limites du rectangle l'englobant. Pour cela, définissez les « Horizontal Overflow » et « Vertical Overflow » à « Overflow ». Centrez-le horizontalement et verticalement. Choisissez la police « PressStart2P-Regular » disponible dans les ressources du projet. Finalement, le texte par défaut doit être « Day 1 » et placez-le comme enfant de « LevelImage ».

Un second texte doit être créé pour le compteur de points de nourriture. Celui-ci est ancré au bas de l'écran. Sa couleur est aussi « blanc », sa taille de 24, centrez-le horizontalement et verticalement et définissez son texte par défaut à « Food : 100 ». La police est la même que pour le texte précédent. Encore une fois, définissez « Overflow » pour les options de surpassement et nommez-le « FoodText ». Finalement, placez le texte avant l'image, dans la hiérarchie, afin que l'image cache le texte lorsqu'affichée.

Désactivez maintenant l'image pour retrouver votre texte et décalez un peu le texte de la nourriture vers le haut.

III-B. GameManager.cs

Maintenant, le script GameManager.cs doit gérer l'interface utilisateur et gérer les transitions.

III-B-1. Fonctionnalités

Deux nouvelles fonctions sont intégrées :

  • OnLevelWasLoaded(), qui est appelée chaque fois qu'une scène est chargée. Dans ce cas, elle permet d'incrémenter le compteur de niveaux et d'appeler InitGame() ;
  • HideLevelImage(), permet de cacher l'image « LevelImage ».

Lorsque « LevelImage » est affichée, les mouvements du joueur sont bloqués.

III-B-2. Script

 
Sélectionnez
using UnityEngine;
using System.Collections;

namespace Completed
{
    using System.Collections.Generic;       // Nous permet d'utiliser les listes.
    using UnityEngine.UI;                   // Nous permet d'utiliser les interfaces utilisateur.
    
    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 Text levelText;                                 // Texte pour afficher le niveau actuel.
        private GameObject levelImage;                          // Image pour bloquer le niveau durant son initialisation. Fond pour levelText.
        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 niveaux.
            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;

            // Récupère une référence sur l'image LevelImage grâce à son nom.
            levelImage = GameObject.Find("LevelImage");
            
            // Récupère une référence sur notre texte composant LevelText grâce à son nom et la fonction GetComponent.
            levelText = GameObject.Find("LevelText").GetComponent<Text>();
            
            // Définit le texte de levelText avec la chaîne de caractères "Day" et lui ajoute le nombre du niveau.
            levelText.text = "Day " + level;
            
            // Définit levelImage comme active pour bloquer la vue du joueur lors de l'initialisation du niveau.
            levelImage.SetActive(true);
            
            // Appelle la fonction HideLevelImage avec une temporisation de levelStartDelay secondes.
            Invoke("HideLevelImage", levelStartDelay);
            
            // 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);
            
        }

        // Cache l'image noire utilisée entre les niveaux
        void HideLevelImage()
        {
            // Désactive le GameObject levelImage.
            levelImage.SetActive(false);
            
            // Définit doingSetup à false permettant ainsi au joueur de se déplacer.
            doingSetup = false;
        }

        
        
        // 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()
        {
            //Définit levelText pour afficher le nombre de niveaux terminés et un message de fin de partie.
            levelText.text = "After " + level + " days, you starved.";
            
            // 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. Player.cs

Le script du joueur doit modifier le texte « FoodText » afin d'afficher la bonne valeur de nourriture.
Dans la fonction Start() et la fonction AttemptMove(), le texte affiché est mis à jour. De plus, un message différent est affiché lorsque le joueur récupère un objet (fonction OnTriggerEnter2D()) ainsi que lorsque le joueur est touché (fonction LoseFood()).

III-C-1. Intégration

Dans l'éditeur, associer « FoodText » au composant « Food Text » du script Player.

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.