Voici un petit news en français pour un exercice qui est demandé sur OpenClassrooms pour un cours Unity3D.
Bon, il était demandé de créer sur Unity 4 mais je n’aime pas utiliser des vieilles technologies. Du coup j’ai développé sous la dernière version en espérant qu’on ne m’en tiens pas rigueur.
Il était demandé de faire un parcours en FPS. En utilisant le prefab FPS d’Unity, je me suis retrouvé sans personnage. Pas d’ombres pour du parcours … Ingérable. Donc premier étape était d’ajouter un personnage avec quelques animations. Direction :
EDIT, le store n’existe plus … il faut aller directement sur https://www.mixamo.com et créer un ID Adobe.
Ce site est idéal pour télécharger un personnage avec quelques animations. Cela me fera découvrir comment gérer les différents animations dans unity … dans quoi je me suis encore lancés !
Bon, l’ajout du personnage était assez simple, un simple glisser / déposer. Mais les textures du model sont en transparent par défaut et Unity ne le reconnait pas. Donc un petit modif manuel s’impose :
Ensuite, téléchargement de quelques animations sur Mixamo et un détours sur le tutoriel d’unity :
https://www.youtube.com/watch?v=Xx21y9eJq1U
A savoir qu’il faut modifier les rigs des animations importés depuis Mixamo en Humanoïde dans Unity pour que cela fonctionne correctement :
J’ai bidouiller un peu avec les motion blenders et importer mes animations. Puis un petit tour par un script C# pour actionner les différents états d’animation. J’ai dû me baser sur des états booliens car je n’arrivais pas à bien gérer les triggers.
J’avoue, je ne suis pas très satisfait du résultat. Des animations ne se déclenchent pas à chaque fois (surtout le saut quand on enchaîne plusieurs sauts tout en courant). Mais je n’arrive pas à isoler la cause pour le moment et vu que c’est un FPS, on ne le remarque pas vraiment. On a surtout un ombre et quelques contours du personnage quand on regarde vers le bas ceux qui rend un peu plus immersif. C’était ceux que je cherchais donc je ne vais pas perdre plus de temps sur quelque chose que n’était pas demandé. Il faut optimiser le temps au maximum !
Bon, si vous êtes ici pour le code, voici le code des déclencheurs (c’est un peu un foutoir de If – Then – Else mais bon !) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityStandardAssets.Characters.FirstPerson; using UnityStandardAssets.CrossPlatformInput; // animations pour le Cours Unity3D OpenClassrooms public class Animation_triggers : MonoBehaviour { private CharacterController CharacterController; [SerializeField] private Animator playerAnim; private float horizontal; private float vertical; private float lastGrounded = 0f; // Use this for initialization void Start () { CharacterController = GetComponent<CharacterController>(); } // Update is called once per frame void Update () { //Checking for jumps if (CrossPlatformInputManager.GetButtonDown("Jump")) { playerAnim.SetBool("Jumping", true); } else { playerAnim.SetBool("Jumping", false); } //checking if grounded and also if falling for anim. playerAnim.SetBool("isGrounded", CharacterController.isGrounded); if (CharacterController.isGrounded) { lastGrounded = 0f; } else { lastGrounded += Time.deltaTime; } if(lastGrounded > 1.5f) // { playerAnim.SetBool("Falling", true); } else { playerAnim.SetBool("Falling", false); } //running, direction and speed playerAnim.SetBool("Running", Input.GetKey(KeyCode.LeftShift)); Vector3 horizontalVelocity = CharacterController.velocity; horizontalVelocity = new Vector3(CharacterController.velocity.x, 0f, CharacterController.velocity.z); float horizontalSpeed = horizontalVelocity.magnitude; playerAnim.SetFloat("Speed", horizontalSpeed); //hor >0 = right //ver >0 = forward horizontal = CrossPlatformInputManager.GetAxis("Horizontal"); vertical = CrossPlatformInputManager.GetAxis("Vertical"); playerAnim.SetFloat("Vertical", vertical); playerAnim.SetFloat("Horizontal", horizontal); if(vertical > 0.1) { playerAnim.SetBool("Forward", true); } else { playerAnim.SetBool("Forward", false); } if (vertical < -0.1) { playerAnim.SetBool("Backward", true); } else { playerAnim.SetBool("Backward", false); } if (horizontal > 0.1) { playerAnim.SetBool("Right", true); } else { playerAnim.SetBool("Right", false); } if (horizontal < -0.1) { playerAnim.SetBool("Left", true); } else { playerAnim.SetBool("Left", false); } } } |
Au lieu de modifier le script FirstPersonControler fournis par unity (et casser le prefab), je préfère récupérer les inputs directement du Character Controler et d’envoyer les éléments directement au Animator d’unity. Je suis sûr que je peux améliorer mes détections et mes problèmes de déclencheurs peuvent être régler dans le script mais je n’ai pas vraiment 3 mois pour tout régler. Puis si je devais faire un jeu, je ferais le code de A à Z plutôt que d’utiliser le prefab d’Unity. Mais c’est ceux qui était demandé dans le cours Unity3D donc on va en rester là pour l’animation !!
Ensuite, je commence à créer mon parcours avec des cubes déformés. 1er test et je me plante dans mes sauts …. Ça promet, je ne suis pas très douée dans le parcours FPS !!!
Du coup, retour au script et création d’un petit zone de déclenchement à Y=-40 pour téléporter le joueur au début du parcours en cas de chute. Rien de bien sorcier, juste un gros cube avec un BoxCollider Is trigger :
Apres m’être planté un bon 50aine de fois sur des sauts, j’ai vu qu’il manquait un indication pour comprendre qu’on est réapparu au début. Alors hop, un petit champ de particules qui durent une seconde et le tour est joué !
(Oui c’est moche, mais c’est fonctionnel !!)
Un petit bout de code attaché aux particule que quand ils s’activent, on les désactive au bout d’un seconde. On n’a pas envie d’avoir ces boules moches dans le visage trop longtemps :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DisableRegenparticles : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnEnable() { Invoke("disableObject", 1); } void disableObject() { gameObject.SetActive(false); } } |
Et le code du déclencheur pour téléporter le joueur au 0.0.0 (enfin 0. 1,5.0 car on ne veut pas passer à travers le sol !!) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerDeathFall : MonoBehaviour { private Vector3 startPosition = new Vector3(0f, 1.5f, 0f); private GameObject particles; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnTriggerEnter(Collider col) { //teleport to start col.transform.position = startPosition; //play particles. then autoDisactivate after set amount of time particles = col.transform.Find("RegenParicles").gameObject; if (particles != null) { particles.SetActive(true); } } } |
Ouf. Maintenant que tout cela est fait, c’est parti pour notre parcours. Dans le cours Unity3D on demande 2 gros plateformes et il faut arriver du point A au point B.
J’ai décidé de partir sur 3 chemins différents.
- Tout droit sera facile. On monte très haut et on saute jusqu’à la plateforme d’arrivé. Mais attention. Les plateformes sont pile à la hauteur pour qu’on puisse passes entre et donc tomber. Puis il y a quelques variations de hauteur qui peuvent surprendre.
- A gauche on commence sur un plan incliné en courbe (j’aurai aimé mettre des boosters la dessus pour faire un effet à la sonic !!) pour arriver sur un nuage de petits plateformes. Il faut bien choisir ou sauter. Il y a des plateformes dont on ne peut plus remonter sur le chemin original.
- Puis à droite, des plateformes incurvés et des sauts très précis. Certains endroits, les sauts sont calculés au millimètre.
Et pour finir. Il est demandé d’ajouter des petits portes pour symboliser le départ et l’arrivé. Un petit empilement de cubes fera l’affaire pour cette fois ci.
Il est demandé dans la vidéo de mettre quelques éléments de décor au loin. Mais je trouve qu’avec mes trois parcours, on a déjà pas mal de visuel intéressant. Puis on ne parle pas du tout de texture dans cette première exercice et j’arrive à saturation de cubes blancs …
J’aurai aimé ajouter des zones déclencheurs au départ et à l’arrivé du parcours avec un calcul du temps, mais je vais patienter pour voir ceux qui est demandé dans le 2eme exercice du Cours Unity3D.
Bon me reste un petit readme et un package unity et j’envoi le tout. Va falloir que je DL également Unity 4 (berk) pour corriger d’éventuels Cours Unity3D des autres élevés !!
Vous pouvez déjà tester le résultat compilé en webplayer ici :
http://starbugstone.eu/_builds/3DJumper/1/
EDIT :
J’ai failli oublier …
Voici les captures de ceux qui était demandé :
Assets organisés dans des dossiers :
Et même la scène est organisé grâce a des “Game Objects” vides (qui permet de créer des dossiers et déplacer tout les objecte d’un seul bloc) !!
Et bien sur, que avec des Prefabs !!
Et bien sur, la camera est dans les FPSController, la camera par défaut n’est plus présent !!
Pingback: Reponses aux commentaires Exercice unity 1 | StarbugStone's Dev Blog
Pingback: Un Booster dans Unity | StarbugStone's Dev Blog