Pour faire suite à l’article Créer un panneau publicitaire simple, voici une autre approche pour réaliser un panneau, avec NGUI cette fois. L’intérêt d’utiliser ce kit est de pouvoir paramétrer facilement le texte et surtout… le traduire ! Nous n’aurons donc plus de textures mais du texte, changeable à volonté. Pourquoi pas même afficher du texte saisi par le joueur?
Disclaimer
Cet article a été originalement écrit le 27/01/2014 sur mon précédent blog. Certaines informations présentées ici peuvent donc ne plus fonctionner telles quelles.
Le setup de base
Pour commencer, on va créer une scène de test. Grosso modo, c’est la même que pour le tutoriel cité plus haut : un cube aplati pour le sol, un contrôler type FPS et une lumière pour y voir clair :
Pour l’occasion, j’ai créé un modèle 3D que nous allons utiliser par la suite. La méthode est bien entendu applicable à n’importe quel modèle 3D. Après, ce n’est qu’une question de réglage.
Plaçons donc ce panneau sur la scène et attaquons avec NGUI. Bon j’ai ajouté un mur aussi, histoire de ne pas avoir un truc qui flotte en l’air sans raison :
(Brève) introduction à NGUI
Avant d’aller plus loin, quelques précisions sur le fonctionnement de NGUI sont de rigueur. Ce n’est pas une extension de la GUI interne d’Unity, c’est un module à part entière qui fonctionne avec des GameObjects. Notez également qu’avec NGUI, il est possible de créer des interfaces dans l’univers 3D : mettre un bouton sur un mur est simple comme bonjour. Enfin, la création est beaucoup plus aisée car directement visible sur la scène et il n’est pas nécessaire d’écrire du code pour voir quelque chose.
Si vous ne possédez pas de licence pour NGUI, sachez qu’il existe une version gratuite. Elle date un peu mais fonctionne très bien. Il se peut qu’il y ait des différences entre cette version et celle que j’utilise actuellement pour présenter ce tutoriel. Ne soyez donc pas surpris si les screenshots ne correspondent pas tout à fait à ce que vous avez.
Vous pouvez récupérer une version gratuite sur ce thread du forum officiel.
Paramétrage initial
Aller, on y va. En installant NGUI, vous verrez apparaitre un nouveau menu dans la fenêtre, vous donnant accès à toute une série d’actions. Créez une nouvelle 3D UI en passant par ce menu :
Un nouvel objet est créé, un UI Root (3D). Déplacez le dans la hiérarchie de la scène afin de le définir comme fils de votre panneau. C’est un point important si vous voulez par la suite transformer votre panneau en Prefab et le réutiliser ailleurs. N’oubliez pas le reset de position.
Passons au réglage de la caméra maintenant. Par défaut, créer une UI va ajouter une caméra pour celle ci. Le principe est simple : rendre la scène, et rendre par dessus l’interface gérée par ce conteneur. Ce n’est pas ce que nous voulons. Dans notre cas, la caméra de cette UI n’a pas d’intérêt car c’est la caméra principale qui « verra » cette interface, dans l’univers 3D (et non en surimpression 2D).
Cette différentiation est faite au niveau des caméras, via le Culling Mask. Ce champ présente la liste des calques du projet :
Lorsqu’un calque est coché, ce la veut dire que la caméra « verra » les éléments placés sur ce calque. Tout ce qui ne sera pas sur les calques cochés sera invisible pour cette caméra. On voit ici que la caméra de notre interface ne rendra que les éléments du calque « UI ». Supprimez cette caméra pour laisser le UI Root (3D) vide.
Pour la suite, je vous conseille de créer un nouveau calque afin de différencier les éléments d’interface 3D des éléments d’interface que vous voudrez afficher à l’écran. Sinon, vous risquez d’avoir des problèmes de rendu par la suite à cause des masques vus plus haut. Pour créer un calque, sélectionnez un objet, n’importe lequel. Dans son inspecteur, une liste déroulante est disponible en haut avec son calque associé. Cliquez sur Add Layer comme suit :
L’inspecteur se transforme pour afficher la liste des calques créés. Ajoutez en un nouveau pour votre UI 3D :
Ceci étant fait, nous pouvons supprimer la caméra de UI Root (3D) qui ne nous est plus d’aucune utilité. N’oubliez pas de changer son calque pour celui créé plus haut :
Il reste une dernière chose à vérifier. Il faut que votre main camera prenne en compte le nouveau calque. Normalement, les nouveaux calques sont activés sur toutes les caméras existantes, mais une vérification rapide ne coûte rien…
Le calque est bien coché, tout est bon. A partir de maintenant, la caméra principale sera en mesure de « voir » les interfaces 3D que nous pourront créer !
Création du panneau
Le paramétrage de base étant terminé, attaquons la création du panneau. Dans l’exemple précédent, pour faire défiler le texte, nous avons joué sur l’offset de la texture. Cette astuce ne sera pas possible ici car… nous n’avons pas de texture !
Continuons, vous allez comprendre… Ajoutez à votre UI Root (3D) un Panel. Rien de visuel, c’est normal. Ce Panel est un conteneur. Ajoutez lui un Label et renseignez sa fonte. Pour aller plus vite, on va utiliser une fonte dynamique :
Toujours rien de visuel dans la scène ? Déplacez un tout petit peu votre UI Root (3D) afin de le faire sortir du panneau. Normalement, vous devriez voir écris en tout petit « New Label »en blanc.
C’est un début mais ne nous arrêtons pas là. L’objectif est de déplacer horizontalement ce Label pour donner l’illusion que le texte défile. Si vous le faites manuellement, vous remarquerez sans surprise que le texte s’affiche en dehors du panneau… J’ai changé sa couleur en noir pour le rendre plus visible.
C’est là que le Panel créé précédemment prend son importance. Sélectionnez le et jetez un oeil à ses propriétés dans l’Inspecteur. Vous le voyez le paramétrage de clipping ? C’est ce que nous allons utiliser. Il est possible de paramétrer un panneau pour qu’il n’affiche que ses enfants qui sont à l’intérieur de ses limites. Pil poil ce qu’il nous faut ! Sélectionnez Alpha Clip pour avoir une coupure franche. Vous pouvez aussi essayer Soft Clip pour avoir un fondu sur les bords de la zone :
Un cadre rose apparait sur la scène et le Label a disparu si vous l’avez déplacé suffisamment loin. A partir de maintenant, tout ce qui est en dehors de ce cadre rose ne sera pas affiché. C’est notre Clipping Box.
Déplacez les poignées pour ajuster la Clipping Box aux limites du panneau physique. Gardez une petite marge à l’intérieur pour éviter tout chevauchement. Pour faciliter cette mise en place, je vous conseille d’aligner votre modèle sur un axe et de fixer l’axe de la caméra (en cliquant sur l’un des axes du repère en haut à droite de la fenêtre Scene) pour être face à votre objet, comme ceci :
Essayez de nouveau de déplacer votre Label maintenant… Il est masqué correctement et n’apparait qu’à l’intérieur du panneau. Nous y sommes presque ! La dernière étape est de le faire défiler. Pour ce faire, il va nous falloir faire quelques paramétrages supplémentaires sur le Label et un peu de scripting.
Sélectionnez votre Label et modifiez le mode d’Overflow pour ClampContent. En sélectionnant ce mode,vous pourrez agrandir horizontalement la zone de texte sans que cela affecte la taille de la fonte. Chose importante pour la suite, si vous voulez afficher du texte très long. Enfin, alignez le texte à gauche en alignant le pivot à gauche comme suit :
Placez maintenant verticalement le libellé comme vous souhaitez le voir apparaitre, puis déplacez le vers la droite du panneau physique afin de le rendre invisible.
Le script qui suit va déplacer le libellé à la vitesse donnée. Lorsqu’il arrive au bout du texte, sa position est réinitialisée et recommence… Pour ne pas avoir de saute du texte, il faut calculer la longueur du Label et connaitre la taille de la zone de clipping. Voilà le script :
public class NGUIBillboard : MonoBehaviour {
public UILabel Label;
public UIPanel Panel;
public float Speed;
private float _labelWidth;
private float _panelWidth;
private float _startX;
void Start () {
_startX = Label.transform.position.x;
_labelWidth = Label.width;
_panelWidth = Panel.width;
}
void Update () {
var move = new Vector3(Speed, 0, 0);
Label.transform.position += move * Time.deltaTime;
if(Label.transform.localPosition.x <= _startX – _labelWidth – _panelWidth/2)
{
var pos = Label.transform.position;
var vect = new Vector3(_startX, pos.y, pos.z);
Label.transform.position = vect;
}
}
}
[/code]
Affectez ce script à votre panneau physique et affectez les paramètres Label / Panel avec les objets correspondants. Renseignez une vitesse (négatif = de droite à gauche) pas très élevée, et savourez le résultat…
Le fait d’ajouter plusieurs panneaux les uns à côté des autres n’est pas un problème, le clipping se fait en toute transparence, et sans douleur :
GUI n’est pas évident à prendre en main au début, mais c’est un outil formidable. Avec un peu de patience, on arrive rapidement à des résultats satisfaisants, voir même surprenants !
Crédits image : Wikimedia Commons