vendredi 29 mars 2013

[Pseudo-Tutorial] Faire de la 2D avec Unity 3D

[Edit 26/01/14 - Cet article a été écrit avant le lancement de la 2D sous Unity, il y a pas mal de nouveaux outils maintenant ce qui rend ce tutorial un peu obsolète je pense, mais personnelement je travaille toujours comme ça]

Salut tout le monde, billet conseils aujourd'hui. Donc non, ceci n'est pas du tout un tutorial mais plus quelques pistes de réflexion si vous comptez faire un jeu en 2D.

Aujourd'hui j'ai reçu un MMS par email (le mooonde change !!! Nooooooooon) et n'ayant pas d'informations sur l'auteur (à part que c'est un numéro SFR) et du fait que je ne puisse pas répondre (pour une raison inconnue, mais bon, connaissant SFR ça ne m'étonnerait pas qu'ils bloquent mon message juste parce qu'il vient de Belgique), il ne me reste qu'à supposer qu'il a été envoyé par un fidèle lecteur de ce blog^^. Voilà, s'il se reconnait, la réponse à sa question précise est en fin du billet vu que je me suis un peu emporté en écrivant l'article. Ma bavarderie me perdra^^.

Vu qu'en plus on me pose souvent la question, autant en faire profiter tout le monde.

Faire de la 2D sous Unity n'est pas très différent que de faire de la 3D. A part que la configuration de la caméra est différente et qu'on travaille avec des "planes" sur lesquels on met des textures plutôt qu'avec des modèles 3D. Après la plupart des gens utilisent des tilesets, des atlas et tout mais moi je suis un gros noob de la vie donc je ne fais pas ça... (Edit 26/01/15 -> Maintenant si^^)

Mais malgré tout il y a quelques différences importantes sur lesquels je vais rapidement passer (et vous donner des liens où trouver plus d'infos).

Choisir ses axes de travail



Vu qu'Unity est un engine 3D, on a à notre disposition 3 axes (X, Y et Z). On ne va généralement en utiliser que deux pour un projet 2D mais vous verrez que le troisième n'est pas en reste pour autant.

Utilisez ceux que vous voulez mais pensez bien que la gravité d'Unity est liée à l'axe Y (je ne sais pas si on peut le modifier, à mon avis oui).

Je conseillerais donc d'utiliser les axes X et Y pour un palteformer et les axes X et Z pour un jeu en vue du haut comme SotM, c'est surtout une question de logique, rien d'obligatoire.

Deuxième truc, le 3e axe... J'ai dit qu'on ne l'utilisait pas généralement... Ça ne veux pas dire qu'il ne faut pas en tenir compte, ce troisième axe va vous permettre de définir ce qui sera affiché au premier plan ou non. C'est important de ne jamais laisser deux objets qui se chevauchent sur le même plan.

Par exemple dans SotM, le joueur est en y = 1 alors que les décors sont généralement en y = 1.2 ou quoi. Si deux objets se chevauchent ça donne ça et c'est très moche:



Autant ça peut vous paraître évident pour le joueur et un arbre autant ce genre de choses peuvent parfois arriver en jeu pour de petits détails. Une torche accrochée à un mur et qui dépasse un peu par exemple. Ou certains ennemis de SotM qui volent par exemple, c'est important qu'ils ne soient pas à la même hauteur qu'un monstre "terrestre" où ils vont se chevaucher (ça n'est pas sale !).

Un truc très très chiant aussi c'est la gestion de ce qui passe devant ou derrière quelque chose. Par exemple ici, le joueur doit passer derrière l'arbre s'il est au dessus, on est d'accord. Maintenant le problème c'est que si je le laisse passer devant l'arbre et que je veux que sa tête passe devant le tronc hé bien c'est tout simplement impossible. Je pense d'ailleurs que pour mon prochain jeu (si je le fais en 2D) je testerai d'abord divers trucs pour contrer ce problème, comme incliner légèrement les décors à la façon de Don't Starve. Mais bon, là on sort déjà de la 2D pure.


En gros ce que j'essaye de vous dire c'est qu'avant de vous lancer directement dans la création de votre jeu, vous devriez réfléchir à ce genre de détails pour éviter les mauvaises surprises (j'assume parfaitement mon choix pour SotM, bien qu'il soit imparfait, mais j’expérimenterai beaucoup plus pour mon prochain jeu, qui sera peut-être en 3D d'ailleurs).

Pensez éventuellement à utiliser différents layers pour un même objet. Par exemple la partie haute d'une table serait en y = 2 et la partie basse en y = 0. C'est ce qui se fait dans RPG Maker, mais ça demande pas mal de boulot en plus vu que vous devez gérer des objets composés de plusieurs parties (là ça peut-être utile d'utiliser des atlas de textures).

Et enfin, pensez bien à désactiver l'axe que vous n'utilisez pas dans les options des rigidbodies si vous en utilisez.

L'éclairage



Un autre choix important. Est-ce que vous allez utilisez un "vrai" éclairage comme Unity offre par défaut, ce que j'ai fait dans SotM ou bien est-ce que vous n'allez pas en mettre et plutôt faire quelque chose à la Zelda où l'éclairage sera le même partout (avec éventuellement un sprite noir, troué au milieu, autour du perso dans les grottes par exemple).

Ce choix est très important, d'abord parce qu'il change énormément le design, ensuite parce qu'un éclairage comme Unity offre pose pas mal de problèmes auxquels on aurait pas pensé. Pour la simple et bonne raison que la distance entre la source de lumière et un "plane" change la luminosité du plane.

Je m'explique, souvent il arrive que je doive changer la hauteur de mes murs selon leur position. Par exemple, la base d'un bâtiment sera en y = 0.6 afin que si le joueur "pousse" contre ce mur et qu'il passe un peu dessus, il s'affiche devant le mur. Par contre un mur à côté d'une porte devra être plus haut que le joueur pour éviter cet horrible effet:


Mon archère est bien derrière la grille, mais pas derrière le mur, d'où cet effet bizarre où sa main passe entre les deux. Pas de problème, je vais rehausser le mur !



Et là c'est le drame, le rendu des blocs à côté de la grille est différent à cause qu'ils sont plus proches de la source lumineuse. Idéalement je vais donc devoir rehausser tous les murs proches pour qu'il n'y ait pas de différence, ou pour faire en sorte qu'elle se voit moins. Notez aussi que sur cette image la lumière semble venir d'en dessous du mur, ce qui donne un effet carrément bizarre.

Bref, pensez à ce genre de petits détails AVANT de vous lancer dans votre jeu. Une petite feature sympa peut vite vous donner beaucoup plus de boulot. Une fois encore ça ne veux pas dire qu'il ne faut pas mettre d'éclairage dans son jeu 2D (il donne d'ailleurs très bien dans SotM^^), ça veux simplement dire qu'il faut être bien conscient des implications que ça aura. Si c'était à refaire par exemple, je placerais toujours mon sol en y = 0 mais je mettrais le joueur en 0.5 (au lieu de 1) afin qu'il y ait moins de différence de niveaux entre les objets devant le joueur et ceux qui doivent s'afficher derrière.

La caméra



C'est vraiment LA différence entre faire de la 2D et de la 3D sous Unity. La caméra sera réglée totalement différemment de celle d'un jeu 2D, pour une raison toute simple:


A gauche, une caméra en mode Perspective, qu'on utilise généralement dans les jeux 3D. A droite, une caméra en mode Orthographique qu'on utilise principalement pour la 2D.

Je vous passe les détails techniques mais en gros: le mode perspective montre les différences de hauteur, ce que ne fais pas l'orthographique.

Donc pour changer ça dans l'éditeur il suffit de cliquer sur le truc que j'ai entouré en rouge. Par contre il va falloir changer ça en jeu. C'est très facile et ça se fait dans l'inspector de la caméra (si vous utilisez une caméra par scène, comme moi, pensez à le faire sur chaque caméra).


Vous devrez ensuite faire des trucs (ce n'est pas sale !) avec la "size" juste en dessous. Pour ça je vous laisse en compagnie de cet article qui vous l'expliquera bien mieux que moi (désolé c'est en anglais).


Les animations

[Edit 26/01/15 -> Terrible, terrible méthode... Elle est simple à mettre en oeuvre mais je vous conseille vraiment de vous pencher sur les atlas de textures. Il va falloir toucher aux UV's du quad (les plaques sur lesquelles vous mettez vos textures) que vous utilisez, ce qui peut être compliqué quand on débute mais ça vous fera gagner un temps infini plus tard. Puis une fois que c'est fait, en principe le script est valable pour toujours, j'essayerai de partager le mien un jour]

Alors là mes conseils sont à prendre avec des pincettes parce que je n'ai aucune idée de comment font les pros ou les autres gens tout simplement.

Personnellement je crée un objet avec plusieurs "planes" (Edit 26/01/14 -> Utilisez des quads, pas des planes) contenant chacun une image de l'animation (je change cette image selon l'orientation du personnage) et ensuite j'active un plane à la fois avec le système d'animation intégré à Unity. Je donne le même nom aux planes ayant la même fonction afin que l'animation soit réutilisable (toute les créatures utilisent la même fonction Walk que le player par exemple).


En gros, l'animation Walk désactive le plane idle et active le plane Walk. Puis refait l'inverse de manière à ce que le perso donne l'impression de marcher en passant du stade "je fais un pas" à "je ne bouge pas".

Je ne sais pas si c'est la manière optimale de faire les choses [Edit: Nope^^]. régler une nouvelle animation est assez pénible mais d'un autre côté il ne faut le faire qu'une seule fois (n'importe quel PNJ possède les animations Walk et Attack). Si vous avez une méthode bien meilleure n'hésitez pas à m'en faire part par mail ou dans les commentaires.

Les collisions

Si vous utilisez le système de collisions d'Unity, une fois encore pensez aux applications pratiques que vous en ferez.

Il y a peu de temps je vous disais que les mobs volants dans SotM pouvaient maintenant voler au-dessus de l'eau. Pourquoi est-ce que ça n'a pas toujours été le cas? Simplement parce que j'avais fait le bourrin avec mes CollisionBox.

Voilà comment sont les box des chauves-souris et de l'eau maintenant:

Chauve-souris a gauche, eau à droite


La box de l'eau ne va que vers le bas, alors que celle de la chauve-souris ne va que vers le haut. Pas de collisions entre eux donc.

Maintenant voilà la collisionBox d'un mur (et les créatures terrestres, genre le joueur ont à peu près la même):


Elle va vers le haut, et bloquera donc la chauve-souris. Et aussi vers le bas, donc euh, elle bloquera tout le reste quoi.

Maintenant imaginons que j'aimerais que les chauves-souris passent aussi au-dessus des PNJ et du joueur, je devrais modifier ceux-ci pour qu'ils n'aient qu'une box qui va vers le bas. Ce que je n'ai évidemment pas fait et qui prendrait trois heures à modifier... Erreur de débutant^^'.

Encore une fois, pensez à ce genre de petits détails AVANT de vous lancer dans votre jeu. Ça vous évitera de perdre du temps plus tard.

Réponse à la question (enfin !)



Voilà voilà. Donc pour répondre à la question précise du mail dont je parlais en début de billet et qui est "Qu'est-ce que j'utilise pour faire de la 2D dans Unity?".

La réponse est simple: Rien du tout ! On peux parfaitement faire de la 2D dans Unity sans utiliser d'outils ou de plugins externes (même si j'ai l'impression que peu de gens le font).

Par contre je vous avoue que pour me simplifier la vie j'utilise mes propres outils, c'est à dire l'éditeur de levels qu'un ami m'a codé en java (edit: l'outil ci-dessous a remplacé l'éditeur, je crée mes niveaux dans Unity).

Ainsi qu'un petit outil intégré à Unity que j'ai codé et qui me simplifie grandement la vie pour le placement de mes murs, sols, etc... (si ça intéresse quelqu'un faites le moi savoir et je partagerai le code un de ces jours après l'avoir un peu "nettoyé" Edit: le voilà).


Je compte écrire un tuto un jour expliquant un peu la base de la création d'outils sous Unity. C'est très facile à faire (je ne parle pas de créer un éditeur 3D, style Blender, dedans hein^^) et ça fais gagner énormément de temps. [Edit: Voici le tuto]

Si malgré tout vous voulez utilisez des outils externes, ce qui n'est pas du tout une mauvaise idée en soi (même si personnellement je n'arrive jamais à rien avec ce genre de trucs), je vous conseille ce tutorial qui je pense est bien foutu.

Voilà, j'espère que la personne m'ayant envoyé le MMS trouvera cette bouteille jetée à la mer et ne croira donc pas que je suis un gros enfoiré qui ne répond pas à ses mails et j'espère aussi que ça en aidera d'autres.

N'hésitez pas à me faire remarquer si j'ai fait des erreurs ou que je donne des conseils tout pourris, je suis loin d'être le dieu tout puissant d'Unity (que j'ai commencé à utiliser il y a à peine 6-7 mois).

A plus sous le bus !