Unity : Résolution d’un problème d’affichage entre deux objets possédant des shaders transparents

J’ai réalisé aujourd’hui quelques correctifs sur mon jeu Bulldozer sortie sur Android l’an dernier, dont la correction d’un problème d’affichage sur les scores affichés quand le Bulldozer se déplace, mais uniquement si le score est affiché au-dessus de la mer.

Le problème survient entre la mer et les objets de type TextMeshPro que j’utilise pour afficher le texte des scores.

Constatation

  • La mer a son propre shader que j’ai récupéré dans un asset.
  • L’objet TextMeshPro utilise une police d’écriture sous forme d’image et son shader sert à définir la façon de rendre la police.

Pour les deux shaders, celui de la mer et celui de la police d’écriture, il y a utilisation du canal alpha. Le canal alpha c’est le canal qui est utilisé pour gérer la transparence. Le canal alpha n’est pas utilisé dans les shaders utilisés les cases, les bulldozers ou les arbres. Or j’ai des problèmes d’affichage uniquement entre la mer et le texte des scores.

Cet élément après de longue recherche m’a fait trouver qu’il y avait des problèmes d’affichages de ce type lorsque deux shaders utilisant la transparence sont paramétrés sur la même renderQueue.

La renderQueue selon la documentation unity c’est ce qui détermine dans quel ordre les objets sont rendus. Dans mon cas les deux étaient paramétrés sur 3000. En modifiant la valeur de la renderQueue de 3000 à 3000-1 soit 2999 pour le shader de mer j’ai résolu le   problème et mes objets s’affichent dans le bon ordre sans se marcher dessus l’un et l’autre.

En conclusion si vous avez des problèmes d’affichage entre deux objets qui utilisent la transparence alors vérifiez et modifiez la valeur de la renderQueue en fonction de l’objet que vous souhaitez voir afficher au-dessus de l’autre.

Télécharger le jeu Bulldozer pour Android

Blender : Modifier le centre d’un objet (version 2.80 et supérieures)

  1. Le widget (axes de déplacements) n’est pas sur le curseur (cible) à l’origine (centre) de la scène
  2. Appuyez sur « Maj »+ »S » en « View mode » pour faire apparaitre le menu et glissez sur « Cursor to world origin »
  3. Toujours en « View mode » déplacez le modèle pour que le widget soit sur l’origine
  4. Passez en « Edit mode » (Tabulation) et sélectionnez tout votre modèle (« A »)
  5. Montez le modèle pour que le bas soit sur le curseur (qui est à l’origine)
  6. Repasser en « View mode » et voilà votre widget (axes de déplacements) est sur l’origine

Cette technique est particulièrement utile pour que vos objet se positionnent sans paramétrage supplémentaire après importation dans Unity par exemple

Comment fermer une fenêtre dans Unity3D ?

Aujourd’hui nous allons essayer de fermer une fenêtre ouverte dans Unity3D. Pour cela il faut une fenêtre ouverte (panel) dans un Canvas.

Problématique :

  • Nous ne voulons pas fermer cette fenêtre (InventoryWindows) d’une quelconque manière mais en appuyant simplement en dehors de celle-ci.
  • Il faut que la fermeture de la fenêtre puisse s’exécuter aussi sur mobile (soit sans curseur de souris).

Dans un premier temps je n’ai pas pensé à adapter cette fonctionnalité à l’utilisation d’un écran tactile. Or, mon premier réflexe a été d’ajouter un contrôle sur un booléen (mouseIsOut), si mouseIsOut vrai alors fermer la fenêtre, sinon ne rien faire. J’ai mis le tout dans la fonction LateUpdate() de la classe définissant la gestion de ma fenêtre. Quand la souris sors du Panel (Event Trigger –  PointerOut) alors on met mouseIsOut à vrai. Au contraire, à l’ouverture du panel ou l’entrée de la souris dans le panel on met mouseIsOut à faux.

Avec cette méthode qui marche très bien sur PC on rencontre bien vite un problème quand on passe sur un écran tactile. En effet, l’écran tactile ne considère pas de curseur tant que notre doit n’est pas en contact avec la surface. On ne peut donc pas détecter la sortie du curseur du Panel à l’aide de l’Event Trigger en mode PointerExit… (Sauf si l’utilisateur déplace son doigt sans le lever de l’intérieur à l’extérieur du panel.

Recherche d’une autre solution :

Pour palier à ce problème j’ai trouvé une solution facile à mettre en œuvre.

  • Faire d’un panel un bouton quitter géant et situé à l’arrière de notre fenêtre.

En bleu (écran + objet actif) vous pouvez voir le panel sur lequel j’ai ajouté un Event Trigger et le script permettant de mettre mouseIsOut à True si il y a détection de clic sur ce panel.

Il vous suffit alors de mettre mouseIsOut à false quand vous ouvrez la fenêtre (ici l’inventaire) et le tour est joué.

Note : vous pouvez aussi détecter si votre fenêtre est active (isActive = true) pour économiser l’utilisation d’un booléen.