Unity UI et interfaces utilisateurs
Présentation générale
1. Définition
Lors du développement d’un logiciel 2D/3D, il est commun de distinguer la scène immersive en plusieurs dimensions de l’interface graphique permettant d’accéder à celle-ci. Dans le monde du jeu vidéo, on distingue par exemple le "jeu" du "menu".
On va donc parler d’interface graphique pour désigner tous les éléments permettant de naviguer au sein des scènes multidimensionnelles ou d’afficher des informations à l’utilisateur.
La création d’un menu efficace à l’aide d’un éditeur dédié à la manipulation d’objets dans des repères à plusieurs dimensions peut être assez fastidieux car l’outil n’est tout simplement pas optimisé pour cette tâche.
2. Un peu d’histoire
Unity propose depuis ses premières versions un système de création d’interfaces graphiques qu’il est possible de trouver sous le nom "Legacy GUI".
Comme nous l’avons déjà vu dans un chapitre précédent, dans ce cadre, la création des éléments se fait de façon programmatique dans la méthode OnGUI du code d’un script. Voici un exemple dessinant un bouton et testant s’il a été cliqué...
Le système de Canvas
1. Définition
Un Canvas est l’élément racine de toute interface graphique. Il est obligatoire et tous les éléments graphiques sont nécessairement à l’intérieur d’un Canvas. Lorsque vous ajoutez un élément d’interface graphique sans qu’un canvas soit déjà présent, Unity en créera un pour vous. Le Canvas sera alors la surface de rendu de votre interface graphique qui se comportera alors comme si elle était dans un monde 2D uniquement.
L’ajout d’un Canvas est fait de cette manière dans l’éditeur :
Dans l’onglet Hierarchy, sélectionnez Create, puis UI puis Canvas.
Le Canvas est maintenant ajouté dans la scène et sélectionné. Renommez-le [UI] MainCanvas.
Qu’il soit sélectionné ou non, un Canvas est toujours visible dans la vue Scene sous la forme d’un rectangle.
Ajoutons maintenant un bouton à ce Canvas (nous étudierons en détail ce composant plus tard) :
Effectuez un clic droit sur le Canvas et sélectionnez UI puis Button.
Vous venez d’afficher votre premier bouton dans la nouvelle interface graphique d’Unity !
2. Nombre de Canvas dans une scène
Il est possible d’ajouter autant de Canvas que voulu dans une scène, chacun avec une configuration différente si nécessaire. Il est aussi possible d’imbriquer des Canvas les uns dans les autres.
L’intérêt de cette solution est d’avoir de meilleures performances : la modification d’un élément d’UI d’un Canvas déclenche le rendu de tous les éléments du Canvas. Ainsi en groupant les éléments d’UI par Canvas, on réduit la charge de redessinage à chaque modification.
3. Les différents modes de rendu
La propriété Render Mode du Canvas permet de configurer la manière dont le Canvas...
Le système de positionnement et d’ancrage
1. Le composant RectTransform
Alors que les éléments de la scène portent un script de type Transform pour être positionnés, les éléments d’UI utilisent un script de type RectTransform. Lorsque vous ajoutez un élément graphique, ce script est automatiquement ajouté et l’Inspector modifie son affichage de façon à afficher le RectTransform à la place du Transform :
Un RectTransform permet de définir la position et la taille d’un élément d’UI sur sa zone de rendu 2D. La manière la plus aisée de procéder est de passer l’éditeur dans le mode "redimensionnement" et d’utiliser la souris pour placer les éléments correctement. Pensez de même à paramétrer la vue en Pivot et en Local pour des manipulations aisées.
Astuce à connaître : maintenez la touche [Shift] enfoncée pendant vos redimensionnements pour conserver le ratio des éléments.
Vous remarquerez aussi dans l’Inspector qu’il est possible d’affecter des propriétés liées à sa position dans une scène 3D : position sur l’axe Z (par rapport au plan de rendu), rotation et redimensionnement sur les trois axes.
Attention cependant, dans le cas d’un composant d’UI, modifier les valeurs de Scale a pour impact de "zoomer" réellement l’élément : les images, polices et autres contenus seront étirés et pourront apparaître de façon dégradée si l’agrandissement est trop élevé.
2. Le système d’ancrage
a. Définition
La position d’un élément d’UI est définie par rapport à des ancres qui définissent une zone d’ancrage. Celle-ci correspond à un rectangle lui-même spécifié par deux points. Unity appelle ces deux points les points minimum et maximum. La zone d’ancrage est représentée dans l’éditeur par quatre petits triangles blanc. Elle peut être réduite à un point unique si nécessaire.
Les coordonnées de ces ancres sont toujours exprimées...
Les différents éléments d’affichage
Unity propose plus d’une dizaine de composants différents d’affichage. Certains sont des scripts simples et d’autres sont des compositions d’éléments de base.
1. Text : afficher un texte
Il s’agit du composant de base permettant d’afficher un texte simple ou riche et de le mettre en forme. Sa propriété principale est évidemment Text qui permet de définir le texte à afficher. Il est possible de choisir la couleur d’affichage en utilisant la propriété Color dans l’Inspector ou le code.
a. Configuration de l’affichage des lettres
Le groupe Character dans l’Inspector permet de choisir la police à utiliser et sa configuration générale :
-
Font : police d’affichage.
-
Font Style : style du texte (normal, gras, italique ou les deux).
-
Font Size : taille (en pixel) d’affichage du texte.
-
Line Spacing : valeur d’interlignage. Cela est pratique pour rapprocher les unes des autres les lignes d’un paragraphe.
Nous verrons plus tard le rôle de la case à cocher Rich Text.
b. Configuration de la disposition
Le groupe Paragraph permet de configurer la disposition du texte par rapport à son RectTransform parent :
-
Alignment : alignement vertical et horizontal du texte.
-
Horizontal overflow : comportement du texte lorsque sa taille ne tient pas horizontalement : sortie de l’élément (Overflow) ou passage à la ligne (wrap).
-
Vertical overflow : comportement du texte lorsque sa taille ne tient pas verticalement : sortie de l’élément (Overflow) ou coupure (Truncate).
-
Best fit : en cochant cette case, la taille de la police sera ignorée et Unity adaptera au mieux la taille de la police pour afficher tout le texte. En cochant cette case, deux champs apparaissent alors pour spécifier les valeurs minimum et maximum de taille de police.
c. Utilisation de texte riche
En cochant la case Rich Text, il est possible d’utiliser un système de balisage pour mettre en forme plus précisément le texte. Les valeurs renseignées sur le composant seront utilisées sauf là où les balises imposeront une différence.
Voici une liste des balises disponibles pour modifier l’affichage :
-
<b> : le texte encadré sera...
Les différents moyens de disposer les éléments
Unity propose aussi des moyens pour disposer ces différents éléments les uns à côté des autres ainsi que pour contrôler la manière dont se comportent leurs dimensions.
1. Layout Element
Le système de disposition des éléments d’interface graphique se repose, dans ses mécanismes intrinsèques, sur un composant nommé LayoutElement. Tous les éléments d’UI disposent de celui-ci même s’il n’est pas visible dans l’Inspector. Afin de permettre une configuration plus personnalisée, il est possible de surcharger cette valeur par défaut par une valeur configurée dans l’Inspector.
Voici la procédure permettant d’ajouter une image dans la scène et de surcharger ses paramètres :
Réalisez un clic droit sur le Canvas parent et sélectionnez UI - Image.
Sélectionnez l’élément nouvellement créé et nommez-le LayoutElementTester.
Cliquez sur le bouton Add Component. Recherchez puis ajoutez le script LayoutElement.
Remarquez que dans la vue de détails de l’Inspector, il est possible de voir les propriétés de disposition par défaut en sélectionnant Layout Properties.
a. Configuration du LayoutElement
Dans l’Inspector, le composant LayoutElement apparaît comme une liste de case à cocher décochée. En en cochant une, il devient possible de personnaliser sa valeur. Certaines valeurs peuvent être grisées si elles sont désactivées par un autre composant du layout sur lesquelles nous reviendrons plus tard.
Voici les propriétés exposées dans l’Inspector :
-
Min Width/Height : correspond à la taille minimum du composant et de ses enfants. Il ne lui sera pas assigné une taille plus petite même s’il ne rentre pas dans son parent.
-
Preferred Width/Height : correspond à la taille optimale souhaitée pour ce composant.
-
Flexible Width/Height : ce paramètre indique au composant Layout parent la proportion pondérée de ce composant à prendre une éventuelle place disponible par rapport aux composants de même niveau que lui. La somme des valeurs...
Localisation d’une application
La création d’une application diffusée dans plusieurs pays est un problème très courant et il est souvent demandé de traduire les textes dans les différentes langues. Cela correspond plus précisément à ces besoins :
-
permettre de stocker les traductions dans un fichier par langue facile à éditer,
-
définir une langue par défaut si la traduction n’existe pas dans la langue de l’utilisateur.
Pour réaliser cette fonctionnalité, il est donc nécessaire d’assigner le texte d’un composant Text en fonction de la langue du système.
1. Logique du composant de traduction
La logique que nous allons implémenter est assez simple au demeurant : nous allons créer un script paramétré par une clé de traduction et ce script sera à poser sur chaque texte à traduire.
Les traductions seront écrites dans des fichiers textes au format générique CSV (une ligne par "valeur" avec chaque ligne composée de colonnes séparées par des points-virgules) présents dans le dossier Resources. Dans notre cas il n’y aura que deux colonnes : une pour une clé et une pour la valeur traduite.
Lors de la première lecture d’une valeur à traduire, le script générera un dictionnaire "clé/valeur" une fois pour toutes et les valeurs seront lues en son sein.
La première manipulation va donc consister à créer un composant Text et lui apposer un script :
Dans la vue Hierarchy, cliquez Create - UI - Text.
Sélectionnez le GameObject Text nouvellement créé par Unity.
Dans l’Inspector, cliquez sur le bouton Add Component et Create Script dans la fenêtre de sélection. Choisissez Localize comme nom de script.
2. Création des fichiers de ressources
Un fichier de traduction CSV sera créé et édité à l’aide d’un éditeur de texte....
Gestion des polices (font)
Les polices sont des éléments bien à part dans Unity et peuvent être utilisées sur un composant Text vu précédemment ou en utilisant le composant historique GuiText.
1. Import d’une police
Unity supporte les polices de types TTF (True Type Font) et OTF (Open Type Font) ainsi que les caractères Unicode nécessaires à l’affichage de texte français, japonais ou encore chinois.
Il suffit de placer un fichier de ce type dans le dossier Asset pour qu’Unity l’importe. Ce processus crée automatiquement une texture et un matériau utilisé par Unity pour faire le rendu de la police là où cela est nécessaire. L’affichage d’un texte consistera à afficher des portions de cette texture.
Il est possible de configurer l’import de la police depuis l’Inspector :
-
Font Size : taille de base de la police utilisée pour générer la texture correspondant à la police. Plus cette valeur est grande, plus la texture générée est grande mais plus les textes affichés avec une grande taille de police sont affichés sans défaut dû à un agrandissement d’une image trop petite.
-
Rendering Mode : mode de rendu utilisé pour générer l’image correspondant à la police. Permet d’affiner la qualité...