Bibliothèque d'exemples¶
Tous les exemples montrés ici sont disponibles sur le projet disponible ici. Vous pouvez le télécharger et explorer avec les sujets en dessous.
Projet Unity de la bibliothèque
Persistance de données¶
Différents scenarios dans le jeux vidéo exigent que certaines variables sont enregistrées entre une scène et l'autre. Par exemple, quand on veut charger une session de jeu antérieure ou le progrès du jeu. Il y a différent façons de planifier et implementer cette fonctionnalités.
High Score persistant ou record de meilleurs scores¶
Unity a un système de persistance appelé PlayerPrefs pour préserver des données simples (comme des variable floats ou de string) entre différents sessions de jeu. Le PlayerPrefs est une classe avec de paires de méthodes pour lire et pour écrire des valeurs à la base de données persistantes, associés à une clef (c.à.d. un id en texte). Par exemple GetInt()
et SetInt()
, GetString()
et SetString()
, etc.
Avec cette système, on a crée une composante HighScorePresistant qui montre le valeur du record et de la pontage actuel à l'écran. Quand le pointage est plus grand que le record, son valeur est enregistrée sur le PlayerPrefs avec la clé HIGHSCORE
(mais qui peu être customisé). Cette vérification est faite chaque foi que le pointage change à travers de la méthode publique OnChangerPointage(int nouvellePointage)
. Dans la scène exemple, on utilise une etiquette en rouge pour montrer le record et une en noir pour montrer la pointage actuel.
Dans cet exemple, les points sont changés à chaque second passé, comme aux jeux arcade de survie et évasions. Le code pour cette comportement de exemple est sur le script ExemplePointage
.
Voici le code pour la composante HighScorePresistant.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class HighScorePersistant : MonoBehaviour
{
// etiquettes UI utilisés pour montrer
// le pointage plus élévé et l'actuel
public TextMeshProUGUI texteHighScore;
public TextMeshProUGUI textePointage;
// clé utilisé pour enregistrer le pointage dans
// la base du PlayerPrefs
public string highscoreClef = "HIGHSCORE";
// variables pour le record et le pointage actuel
private int _highScoreActuel = 0;
private int _pointageActuel = 0;
void Start()
{
// initialisation de pointage
_pointageActuel = 0;
// chargement du record enregistré avec la highscoreClef
// si il n'y a pas de record, la valeur sera 0
_highScoreActuel = PlayerPrefs.GetInt(highscoreClef, 0);
// actualise les etiquettes de l'UI
texteHighScore.text = _highScoreActuel.ToString();
textePointage.text = _pointageActuel.ToString();
}
// cette méthode est publique, donc elle peut être
// appellé à partir d'autres composantes
public void OnChangerPointage(int nouvellePointage)
{
// changer le pointage actuel
_pointageActuel = nouvellePointage;
// si c'est le nouveau record
if (_pointageActuel > _highScoreActuel)
{
_highScoreActuel = _pointageActuel;
// enregistrement du nouveau record
PlayerPrefs.SetInt(highscoreClef, _highScoreActuel);
}
// actualise les etiquettes de l'
textePointage.text = _pointageActuel.ToString();
texteHighScore.text = _highScoreActuel.ToString();
}
}
Décomptes et timers¶
Méthode Invoke()
et InvokeRepeating()
¶
La méthode Invoke()
nous permet d'exécuter une méthode dans le même script après un délai initial. Avec la méthode InvokeRepeating()
on peut choisir un délai initial et un intervalle pour répéter l'exécution.
Voici un exemple d'utilisation de ces 2 méthodes au Start()
.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonScriptInvoke : MonoBehaviour
{
void Start()
{
// Exécution initiale après 3s seulement
Invoke("MonMethodeExemple", 3f);
// Exécution initiale après 5s avec repétition à chaque 10s
InvokeRepeating("MonMethodeExempleRepetee", 5f, 10f);
// La méthode en dessous annule toutes les
// exécutions faites avec Invoke() ou InvokeRepeating()
// CancelInvoke();
}
void MonMethodeExemple()
{
Debug.Log("Juste une méthode exemple.");
}
void MonMethodeExempleRepetee()
{
Debug.Log("Juste une méthode exemple repetée.");
}
}
Voici le résultat dans la Console (notez les timecodes) :
Coroutines¶
Les coroutines vont nous permettre de "pauser" une méthode dans le même script et de la continuer après un délai. Les étapes pour les utiliser sont:
- Il faut déclarer une méthode du type
IEnumerator
. - Après, on peut l'exécuter avec la méthode
StartCoroutine()
.
Voici un exemple de script avec une définition et une exécution de coroutine.
using UnityEngine;
using System.Collections;
public class MaCoroutineSimple : MonoBehaviour
{
void Start()
{
Debug.Log("Message avant d'exécuter la coroutine");
// Appel de la coroutine que j'ai définie
// en-dessous au moment où mon script
// est activé dans la scène.
StartCoroutine("MaCoroutine");
Debug.Log("Message pendant la pause");
}
// Définition d'une coroutine
public IEnumerator MaCoroutine()
{
Debug.Log("Instruction avant la pause");
// Pour appliquer une pause avec un délai à la coroutine
yield return new WaitForSeconds(1f);
Debug.Log("Instruction après la pause");
}
}
Le résultat de cette coroutine sur notre Console (notez les timecodes) :
Minuterie avec événements¶
La composante MinuterieEvents nous permet de configurer 2 événements différents au Inspector : un exécute à chaque second (OnChaqueSecond(int secondActuel)
) et l'autre quand le comptage termine (OnTermine()
). Avec cette composante et le prefab MinuterieAvecEvenements, la scène montre un Text dynamique à l'écrán et on peut configurer multiples comportements pour ces deux événements avec nos scripts.
Voici le code pour la composante. Il utilise une coroutine qui active les méthodes configurés aux moments adéquats.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
public class MinuterieEvents : MonoBehaviour
{
public int duration = 60;
public bool compterLeZero = false;
private TextMeshProUGUI _texte;
private int _compteur;
public UnityEvent<int> onChaqueSecond;
public UnityEvent onTermine;
void Start()
{
_texte = GetComponentInChildren<TextMeshProUGUI>();
StartCoroutine("CommencerMinuterie");
}
IEnumerator CommencerMinuterie()
{
_compteur = duration;
_texte.text = _compteur.ToString();
while (_compteur >= 1)
{
yield return new WaitForSeconds(1f);
_compteur -= 1;
onChaqueSecond.Invoke(_compteur);
_texte.text = _compteur.ToString();
}
if (compterLeZero == false) {
yield return new WaitForSeconds(1f);
}
onTermine.Invoke();
}
}
Minuterie avec redémarrage¶
Le prefab MinuteRedemarrage combine la composante MinuterieAvecEvents avec un script que redémarre la scène actuel quand le comptage termine. Pour utiliser le prefab, il faut juste l'ajouter à la scène. Voici sa configuration base.
Contrôle d'UI et menus¶
Événement avec méthode préexistante¶
On peut utiliser les événements pour exécuter différents méthodes déjà disponibles sur un GameObject de la scène. Un exemple important est l'activation (ou désactivation) d'un GameObject. Pour faire ça, on connecte le GameObject avec le champ sous "Runtime Only" et après on peut choisir une méthode liste sur le dropdown à droite et configurer ses paramètres (ex. le checkbox).
Voici l'événement sur l'Inspector (dans une composante Button d'un bouton à mon Canvas) :
Cette configuration va exécuter la méthode SetActive()
du GameObject MonObjetExemple avec une valeur de true
(checkbox est coché). L'objet va être activé sur la scène.
Événement avec méthode originale¶
Pour exécuter une méthode originale (c.à.d. créée dans un de nos scripts) dans un événement de l'Inspector, il faut que 1) le script avec la méthode soit attaché a un GameObject de la scène, et 2) que cette méthode soit publique.
Voici mon script (appelé MonScriptExemple
et attaché à un objet MonObjetExemple à la scène) :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonScriptExemple : MonoBehaviour
{
// Cette méthode va être disponible sur la boite
// d'événement parce qu'elle est publique
public void MonMethodeExemple()
{
Debug.Log("La méthode exemple a executé.");
}
}
Voici l'événement sur l'Inspector (dans une composante Button d'un bouton à mon Canvas) :
Activation simple d'élement d'UI¶
On peut utiliser l'Événement avec méthode préexistante pour créer des boutons pour activer et désactiver des panneaux et d'autres éléments de l'interface utilisateur.
Voici un exemple de Canvas avec différents boutons (Activer, Désactiver et X) qui utilisent les événements et la méthode GameObject.SetActive()
pour contrôler le Panel à droite.
Voici la configuration des événements pour chaque Button :
Changer les propriétés de l'UI à partir d'un script¶
De façon générale, le processus pour changer une propriété d'UI à partir d'un script a la structure suivante :
- Déclarer une variable publique du type de la composante ciblée (ex.
TextMeshProUGUI
pour texte,Image
pour une image, etc). - Dans l'Inspector, connecter la variable du script avec le GameObject de l'élement d'UI à l'Hierarchy.
- Changer les valeurs des propriétés de notre variable dans le script (ex.
monTextUI.text
,maImage.color
).
L'exemple suivant montre des changements pour 3 types d'élement d'UI : Text, Slider et Image.
Sur l'Inspector :
Dans notre script MonScriptChangerUI
:
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class MonScriptChangerUI : MonoBehaviour
{
// Ces variables vont être configurées
// dans l'Inspector
public TextMeshProUGUI textChrono;
public Slider sliderOnde;
public Image imageAlternance;
void Update()
{
// Montrer le temps depuis le démarrage sous forme de texte
textChrono.text = Time.time.ToString("00.0");
// Montrer la valeur d'une onde avec un slider
sliderOnde.value = Mathf.Sin(Time.time) * 0.5f + 0.5f;
// Changer la propriété color de l'Image pour donner une teinte
// à partir de la valeur du slider
if(sliderOnde.value < 0.5f )
{
imageAlternance.color = Color.red;
}
else
{
imageAlternance.color = Color.blue;
}
}
}