Animer un personnage de jeu vidéo peut s’avérer complexe et requiert une compréhension approfondie des outils d’animation.
Sans une animation fluide, les mouvements peuvent sembler irréalistes, affectant l’expérience utilisateur et l’interactivité du jeu.
Cet article vous guide dans le processus d’importation et d’animation de personnages 3D dans Unity, en intégrant des mouvements réalistes et des interactions précises.
Apprenez à donner vie à vos personnages grâce à l'animation 3D.
Table des matières
Présentation du personnage 3D animé
Dans cette série d’articles, nous allons pas à pas créer un personnage de jeu vidéo. Cet exercice posera un cadre concret et pratique pour appliquer nos précédents acquis.
Dans le cadre du présent projet, nous vous fournirons un modèle 3D que nous allons progressivement rendre interactif en y intégrant des animations et logiques au nombre desquelles nous pouvons citer :
- Idle :décrivant l’état Inactif,
- Marche :mouvement en avant et arrière,
- Rotation :pratique pour faire tourner le joueur
- Course :pour permettre au joueur de courir,
- Saut :cette partie n’est pas aussi simple qu’il y paraît ; mais nous relèverons ensemble le défi,
- Chute :une animation spécifique à déclencher spécifiquement lorsque le joueur ne sera plus en contact avec le sol.
- Accroupi :permet au joueur de passer en dessous de différents obstacles
Rendez-vous à l’article suivant pour entrer dans le vif du sujet.
Importation et préparation du modèle 3D
C’est le moment d’importer notre modèle 3D Astra. Nous allons faire quelques configurations de bases pour apprêter le modèle.
Commencez par étendre une plane sur la scène pour faire office de sol puis importez le modèle 3D Astra disponible dans les ressources. Configurer de façon adéquate le modèle comme nous le faisions précédemment. Placez le modèle sur la scène du jeu et ajoutez :
- UneCapsule Collider
: en plaçant la caméra en mode isométrique et en oscillant sous plusieurs angles de vue ; vous serez en mesure de contenir le modèle à l’intérieur du collider.
- UnRigidbody :à partir de l’option Freeze Rotation, bloquez la rotation sur les axes X, Y, Z pour éviter des comportements indésirables liées à la physique.
Dans l’article suivant, nous allons nous intéresser à l’animation Idle.
Créer l’animator pour position inactive
Cette partie sera assez courte et pour cause le processus vous ai déjà familier. Nous allons simplement configurer l’animation Idle autrement dit l’animation de la position Inactive.
Commencez par créer un Animator Controller et renommez-le « Astra Animator Controller ». Prenez le temps de parcourir les différentes animations du modèle Astra pour les configurer et proprement les renommer avec des noms descriptifs. Ensuite affectez l’animator au modèle 3D puis ajoutez l’animation Idle qui sera d’emblée définit comme animation par défaut. Assurez-vous que le loop time de l’animation Idle soit bien sûr activé.
Le tour est joué ! Pour appréciez le résultat, lancez Unity. Dans l’article à suivre nous allons implémenter l’animation de marche.
Animation marche avant et arrière
Nous allons dans cet article implémenter toute la logique liée à la marche avant et arrière. Pour cela nous aurons besoin de l’animation Walking .
Nous aurons besoin de créer un paramètre de type float à nommer « AxisV ». Rajoutons à l’animator, l’animation Walking avec l’option loop time activée. Pour la marche arrière, il nous suffira de dupliquer Walking, le renommer en « Walking Back » puis en changeant la valeur de son speed à -1 . Définissez les transitions entre Idle – Walking d’une part et Idle – Walking Back d’autre part comme suit :
Transition | Condition |
---|---|
Idle > Walking | AxisV > 0,1Has Exit Time : false |
Walking > Idle | AxisV < 0,1Has Exit Time : false |
Idle > Walking Back | AxisV < - 0,1Has Exit Time : false |
Walking Back > Idle | AxisV > – 0,1Has Exit Time : false |
Créons à présent un script AstraController pour gérer le déplacement :
usingUnityEngine;
publicclassAstraController : MonoBehaviour {
privateAnimator animator;
privatefloataxisV;
[SerializeField] floatwalkSpeed = 2f;
voidStart() { animator = GetComponent(); }
voidUpdate() {
// Récupère l'axe vertical (avant/arrière) via les entrées du joueur (W/S ou
// flèches haut/bas)
axisV = Input.GetAxis("Vertical");
// Passe la valeur d'AxisV à l'Animator pour jouer l'animation
// correspondante
animator.SetFloat("AxisV", axisV);
// Si le joueur appuie sur une touche directionnelle (valeur non nulle),
// déplacer le personnage
if (axisV != 0)
transform.Translate(Vector3.forward * axisV * walkSpeed * Time.deltaTime);
}
}
Ajoutez ce script au modèle et lancez Unity. Tout devrait bien fonctionner. Cependant, vous auriez remarqué qu’entre la marche avant et arrière, le personnage transite invariablement par Idle. Pour corriger cela, définissez pour chacune des 4 transitions, Interruption Source : Next State . Ainsi l’animation Idle sera ignorée et on se donne rendez-vous à l’article suivant pour l’animation de course.
Animation course personnage jeu vidéo
Notre personnage devrait avoir la possibilité de courir lorsqu’on appuie sur une touche bien spécifique. Nous allons bientôt implémenter cette logique.
Une nouvelle animation entre en scène : Running . Rajoutez-la à l’animator et créez un paramètre de type bool « IsRunning ». Créez ensuite des transitions entre Walking et Running comme suit :
- Walking> Running :IsRunning = true
- Running > Walking :IsRunning = false
Prenez le soin de désactiver Has Exit Time pour chaque transition. Entrez la valeur Next State pour Interruption Source si vous souhaitez une transition directe de Running à Idle . A présent, il ne nous reste qu’à étoffer comme suit le code :
usingUnityEngine;
publicclassAstraController : MonoBehaviour {
privateAnimator animator;
privatefloataxisV;
[SerializeField] floatwalkSpeed = 2f;
// Booléen qui indique si le personnage court
privateboolisRunning = false;
// Vitesse de déplacement en courant, modifiable dans l'Inspector
[SerializeField] floatrunSpeed = 6f;
voidStart() { animator = GetComponent(); }
voidUpdate() {
axisV = Input.GetAxis("Vertical");
animator.SetFloat("AxisV", axisV);
// Détermine si le personnage court : avance et appuie sur Left Control
isRunning = axisV > 0 && Input.GetKey(KeyCode.LeftControl) ? true : false;
// Détermine la vitesse actuelle : course ou marche
floatcurSpeed = isRunning ? runSpeed : walkSpeed;
// Passe la valeur booléenne "IsRunning" à l'Animator pour activer
// l'animation de course
animator.SetBool("IsRunning", isRunning);
if (axisV != 0)
transform.Translate(Vector3.forward * axisV * curSpeed * Time.deltaTime);
}
}
En somme, notre script détermine à présent si le personnage marche ou court et met à jour la position en conséquence, tout en transmettant les paramètres à l’Animator pour jouer les animations appropriées.
Dans l’article prochain nous allons apprendre à synchroniser les bruits de pas à l’aide des Events d’animation.
Gestion des FootSteps en animation
Comme nous le savons déjà, les Events d’animation offrent un moyen flexible de déclencher des actions précises pendant le déroulement d’une animation. Dans notre cas, ils nous seront utile pour implémenter les foot steps du personnage.
Pour chacune des animations Walking, Walking Back et Running accédez au sous-menu Events. Sur la timeline, ajouter un event à l’endroit précis où vous voulez qu’un son soit joué. Après avoir ajouté l’Event, de petites icônes d’événement apparaîtront sur la timeline. Utilisez les pour afficher la fenêtre de configuration de chaque Event.
Entrez « FootSteps » dans l’option Function Name. C’est la fonction que nous allons bientôt créer pour déclencher des sons spécifiques. Pour l’option Object utilisez le script AstraController que nous allons d’ailleurs étoffer comme suit :
usingUnityEngine;
publicclassAstraController : MonoBehaviour {
privateAnimator animator;
privatefloataxisV;
[SerializeField] floatwalkSpeed = 2f;
[SerializeField] floatrunSpeed = 6f;
// Indices pour choisir et mémoriser le son de pas
privateintindexFoot = 0, lastIndex;
// Variable pour vérifier si le personnage court
privateboolisRunning = false;
// Référence à l'AudioSource et tableau de sons de pas
privateAudioSource audioSource;
[SerializeField] AudioClip[] sfxFoot;
voidStart() {
// Initialisation de l'Animator
animator = GetComponent();
}
voidUpdate() { /***/ }
publicvoidFootSteps() {
// Choisit un son de pas aléatoire
indexFoot = Random.Range(0, sfxFoot.Length);
// Assure que le son actuel est différent du dernier joué
while (lastIndex == indexFoot) {
indexFoot = Random.Range(0, sfxFoot.Length);
}
// Joue le son sélectionné et met à jour le dernier index
audioSource.PlayOneShot(sfxFoot[indexFoot]);
lastIndex = indexFoot;
}
}
Nous utilisons la méthode FootSteps () pour jouer un son de pas aléatoire ; en veillant à ne pas répéter le dernier joué. Le son est sélectionné dans un répertoire de son que nous allons renseigner en accédant à la propriété sfxFoot dans l’inspecteur. Les audio ad-hoc sont disponibles dans les ressources. N’oubliez pas de rajouter un composant Audio Source et d’ajuster le volume du son afin qu’il ne soit pas trop élevé.
Nous allons garder l’élan en continuant d’améliorer le personnage. Très prochainement, il s’agira d’implémenter la rotation.
Rotation du personnage dans Unity
Il en va d’un certain réalisme que notre personnage puisse être en mesure de tourner dans un sens ou dans un autre en fonction des entrées du joueur. C’est la logique que nous allons implémenter dans cette partie.
Dans l’animator, commençons par ajouter un nouveau paramètre de type float « AxisH ». L’essentiel de logique peut s’implémenter à l’intérieur de notre code :
usingUnityEngine;
publicclassAstraController : MonoBehaviour {
privateAnimator animator;
// Variables pour stocker les valeurs des axes de déplacement
privatefloataxisV, axisH;
[SerializeField] floatwalkSpeed = 2f;
[SerializeField] floatrunSpeed = 6f;
// Vitesse de rotation du personnage
[SerializeField] introtationSpeed = 80;
privateintindexFoot = 0, lastIndex;
privateboolisRunning = false;
privateAudioSource audioSource;
[SerializeField] AudioClip[] sfxFoot;
voidStart() { /***/ }
voidUpdate() {
/***/
// Récupère l'entrée utilisateur pour le déplacement horizontal
// (gauche/droite)
axisH = Input.GetAxis("Horizontal");
animator.SetFloat("AxisH", axisH);
/***/
// Effectue une rotation du personnage en fonction de l'entrée horizontale
transform.Rotate(Vector3.up * axisH * rotationSpeed * Time.deltaTime);
}
publicvoidFootSteps() { /***/ }
}
La rotation du personnage est effectuée avec la méthode transform.Rotate, qui fait pivoter le personnage autour de l’axe vertical (Y) en fonction de la valeur de axisH et de la rotationSpeed. La rotation est ainsi proportionnelle à l’entrée horizontale, permettant un contrôle fluide de la direction.
Lancez Unity et vous noterez que notre nouvelle mécanique fonctionne correctement. Enfin presque ! Il nous faudra rajouter des animations à l’état idle puisse que les rotations ne sont pas trop réalistes.
Pour cela, quoi de mieux qu’un blend Tree. Grâce l’option « Create new blend tree in state », transformez l’animation Idle en un blend Tree dans lequel vous assemblerez les animations comme suit :
Le blend tree dépend de la valeur de « AxisH » permettant ainsi de tourner à gauche ou à droite en fonction de la valeur positive ou négative du paramètre. À noter qu’il suffit d’affect une valeur négative (ici – 1 pour Turning ) au speed d’une animation pour qu’elle joue en sens inverse. D’où Turning a été utilisé par deux fois.
Nous nous apprêtons à implementer l’une des mécaniques les plus stimulant de ce cours : le saut. Rendez-vous à la section suivante.
Implémentation du saut personnage
Dans le développement de jeux vidéo, ajouter la capacité de saut à un personnage est une fonctionnalité essentielle qui améliore le réalisme et l’interactivité du gameplay. Dans Unity, l’implémentation du saut implique l’utilisation de composants physiques tels que le Rigidbody, combinés à une vérification de l’état du personnage (au sol ou en l’air) pour gérer les conditions de saut. Dans cet article, nous allons explorer les différentes étapes pour implémenter le saut du personnage, y compris la configuration des forces physiques, la détection de contact avec le sol, et l’ajout d’effets sonores pour renforcer l’immersion.
Une approche brute d’implémenter le saut, peut se décrire comme suit :
usingUnityEngine;
publicclassAstraController : MonoBehaviour {
/***/
// Force du saut appliquée au personnage
[SerializeField] intjumpForce = 200;
/***/
// Référence au composant Rigidbody pour appliquer les forces physiques
privateRigidbody rb;
voidStart() {
/***/
rb = GetComponent();
}
voidUpdate() {
/***/
if (Input.GetKeyDown(KeyCode.Space)) {
rb.AddForce(Vector3.up * jumpForce);
}
/***/
}
}
Nous utilisons juste le rigidbody pour appliquer une force vers le haut quand la touche espace est appuyée. Cela fonctionne, mais on n’a pas suffisamment de contrôle. Par exemple, les saut peuvent s’accumuler de façon peut réaliste. C’est pour cette raison que nous utiliserons en addition la méthode Physics.CheckSphere .
Commençons par créer à l’intérieur du modèle 3D une toute petite sphère (scale x,y,z : 0,2) que nous positionnerons aux pieds du personnage afin de détecter lorsqu’il touche le sol. Bien sûr, supprimez le collider ainsi tout détail qui ne vous semble pas important. Renommez la sphère « GroundCheck ».
Prenez le temps de créer un layer Player et de l’affecter au personnage tout en veillant à ce que GroundCheck reste sur le layer Default . Au niveau de l’animator, nous ajouterons un nouveau paramètre à la liste : IsGrounded , un booléen.
Revenons à présent à notre script pour l’améliorer :
publicclassAstraController : MonoBehaviour {
/***/
[SerializeField] intjumpForce = 200;
// Clip audio pour le son du saut
[SerializeField] AudioClip sfxJump;
// Masque de couche pour vérifier les collisions au sol
[SerializeField] LayerMask lm;
privateRigidbody rb;
// Indicateur pour savoir si le personnage est au sol
privateboolisGrounded = false;
// Référence à l'objet qui vérifie le contact avec le sol
privateTransform groudCheck;
voidStart() {
/***/
// Initialisation du Rigidbody et de la position de vérification du sol
rb = GetComponent();
groudCheck = transform.Find("GroundCheck");
}
voidUpdate() {
/***/
// Vérifie si le personnage est au sol en utilisant Physics.CheckSphere
isGrounded = Physics.CheckSphere(groudCheck.position, 0.2f, lm);
// Met à jour le paramètre d'animation "IsGrounded" pour indiquer si le
// personnage est au sol
animator.SetBool("IsGrounded", isGrounded);
// Si la touche espace est pressée et que le personnage est au sol, il saute
if (Input.GetKeyDown(KeyCode.Space) && isGrounded) {
// Applique une force vers le haut pour réaliser le saut
rb.AddForce(Vector3.up * jumpForce);
// Joue le son du saut
audioSource.PlayOneShot(sfxJump);
}
/***/
}
}
Notre script gère le saut du personnage en vérifiant si celui-ci est au sol et en appliquant une force verticale lorsqu’une touche de saut est pressée.
La méthode Physics.CheckSphere est utilisée pour détecter le contact avec le sol en créant une sphère de détection autour de GroundCheck . Si la sphère touche une surface définie par le LayerMask spécifié, le personnage est considéré comme étant au sol (isGrounded = true). Cette vérification permet de contrôler quand le saut est autorisé.
Si le joueur appuie sur la touche espace et que le personnage est au sol, une force verticale ( jumpForce ) est appliquée à l’aide du Rigidbody pour effectuer le saut, et un son de saut est joué pour plus de réalisme.
Bien sûr, n’oubliez pas de renseigner le layer avec la valeur « default » dans via l’inspecteur. Maintenant que vous avez les bases pour implémenter le saut, nous allons rajouter de l’animation pour créer une expérience de jeu plus fluide et engageante.
Animation saut personnage Unity
L’animation du saut est une composante essentielle pour rendre le mouvement d’un personnage plus réaliste et dynamique dans un jeu vidéo. Elle nécessite une synchronisation entre les actions physiques du personnage (comme l’application de la force de saut) et les changements d’animations pour indiquer visuellement l’état du saut (montée, flottement, chute, etc.). Dans cet article, nous détaillerons comment mettre en place une animation de saut en utilisant Unity, avec un focus sur les transitions entre les différents états du saut.
Pour animer le saut d’un personnage, il est important de prendre en compte : l’application de la force pour effectuer le saut, la détection de contact avec le sol ainsi que la mise à jour des animations en fonction des mouvements verticaux du personnage.
Un élément clé que nous utiliserons à partir du rigidbody sera la vélocité. Durant le saut, elle est positive lors de la montée et négative lors de la descente . Le paramètre float « VelocityY » que nous ajoutons dans l’animator nous permettra d’y faire référence. Nous aurons également besoin d’ajouter d’un trigger « Jump » pour déclencher le saut.
Le code suivant est plus descriptif de l’usage qui en sera fait :
publicclassAstraController : MonoBehaviour {
/***/
voidStart() { /***/ }
voidUpdate() {
/***/
if (Input.GetKeyDown(KeyCode.Space) && isGrounded) {
rb.AddForce(Vector3.up * jumpForce);
audioSource.PlayOneShot(sfxJump);
// Déclenche l'animation de saut
animator.SetTrigger("Jump");
}
// Met à jour l'animation avec la velocité verticale actuelle du personnage
animator.SetFloat("VelocityY", rb.velocity.y);
/***/
}
}
La vélocité verticale du personnage ( rb.velocity.y ) est mise à jour à chaque frame pour ajuster l’animation. Cela permet de différencier visuellement les phases du saut (montée et descente).
Transitions et conditions d’animation
L’animation du saut peut être divisée en plusieurs états : montée, flottement, chute-atterrissage. Nous allons créer un nouveau Layer du nom de « Jumping » qui contiendra les animations : Jumping Up, Floating et Falling To Landing. N’hésitez pas à ajuster et sélectionner via la timeline les parties les plus pertinentes de chaque animation.
Transitions | Conditions |
---|---|
Any State > Jumping Up | Trigger « Jump » |
Jumping Up > Floating | VelocityY < 0 |
Floating > Falling To Landing | IsGrounded = true |
Falling To Landing > Idle | AxisV < 0.1Has Exit Time = true |
Falling To Landing > Walking | AxisV > 0.1 |
Falling To Landing > Running | IsRunning = true |
Falling To Landing > Walking Back | AxisV < - 0.1 |
Une fois que le saut est maîtrisé, la gestion de l’animation de la chute devient cruciale pour une expérience de jeu plus immersive. Nous verrons comment ajouter des transitions d’animation pour simuler la chute du personnage dans la prochaine section.
Gestion chute dans l'animation
Continuons d’améliorer l’animation de notre personnage pour le rendre plus interactif. Dans cet article, nous allons nous intéresser à l’animation de la chute.
Nous savons déjà comment détecter à partir du code le moment où le personnage est entrain de chuter. Il nous suffit de construire notre logique sur cette base :
usingUnityEngine;
publicclassAstraController : MonoBehaviour {
/***/
privateAudioSource audioSource;
[SerializeField] AudioClip[] sfxFoot;
[SerializeField] AudioClip sfxJump, sfxLanding;
privateboolisGrounded = false;
privateboolisJumping = false;
privateTransform groudCheck;
voidStart() {
/***/
rb = GetComponent();
audioSource = GetComponent();
groudCheck = transform.Find("GroundCheck");
}
voidUpdate() {
/***/
if (Input.GetKeyDown(KeyCode.Space) && isGrounded) {
rb.AddForce(Vector3.up * jumpForce);
audioSource.PlayOneShot(sfxJump);
animator.SetTrigger("Jump");
// Marque le personnage comme étant en train de sauter.
isJumping = true;
}
/***/
// Détecte si le personnage est en train de tomber.
boolisFalling =
!isGrounded && !isJumping && rb.velocity.y < 0 ? true : false;
// Met à jour l'état de l'animation de chute.
animator.SetBool("IsFalling", isFalling);
/***/
}
publicvoidLanding() {
// Joue le son d'atterrissage quand le personnage touche le sol.
audioSource.PlayOneShot(sfxLanding);
// Réinitialise l'état de saut.
isJumping = false;
}
}
La logique de chute repose sur trois conditions :
- Le personnage n’est plus au sol ( !isGrounded ).
- Le personnage n’est pas en train de sauter ( !isJumping ).
- La vitesse verticale du personnage est négative ( rb.velocity.y < 0 ), ce qui signifie qu’il descend.
Lorsque ces conditions sont remplies, l’état de chute est activé via l’animation ( isFalling ). Lorsque le personnage touche à nouveau le sol après un saut, la méthode Landing() est appelée. Cette méthode joue un son d’atterrissage (sfxLanding) et remet la variable isJumping à false, signalant la fin du saut.
Il ne nous reste plus qu’à :
- créer via l’animator le paramètre booléen IsFalling,
- créer une transitionAny State > Floatingayant pour conditionIsFalling :true,
- ajouter à l’animation Falling To Landing un event référençant la fonction Landing ().
Voilà une bonne chose de faite. Dans l’article à suivre nous aborderons l’animation accroupie.
Animation accroupie personnage 3D
L’animation d’un personnage accroupi dans un jeu est essentielle pour donner un aspect réaliste à ses mouvements. Le joueur doit ressentir une différence dans les actions du personnage selon qu’il est debout ou accroupi. Cela peut affecter la vitesse de déplacement, la hauteur des sauts, et même la furtivité.
Comme vous pouvez vous y attendre, nous allons faire quelques modifications dans l’animator :
- Ajouter le paramètre booléen IsCrouched
- Créer un Sub State Machine nomméCrouchcontenant les animations :Crouch Idle , Crouched,Crouched Back
Transitions | Conditions |
---|---|
Crouch Idle > Crouched | AxisV > 0.1 |
Crouched > Crouch Idle | AxisV < 0.1 |
Crouched > Walking | IsCrouched = falseAxisV > 0.1 |
Walking > Crouched | IsCrouched = true |
Crouch Idle > Crouched Back | AxisV < -0.1 |
Crouched Back > Crouch Idle | AxisV > -0.1 |
Crouched Back > Idle | AxisV < - 0.1 |
Crouch Idle > Idle | IsCrouched = false |
Idle > Crouch Idle | IsCrouched = true |
Walking Back > Crouch Idle | IsCrouched = true |
Rajoutons quelques logiques supplémentaires dans le code avant de lancer Unity :
usingUnityEngine;
publicclassAstraController : MonoBehaviour {
/***/
// La vitesse réduite du personnage lorsqu'il est accroupi
[SerializeField] floatcrouchSpeed = 1f;
/***/
privateboolisGrounded = false;
privateboolisJumping = false;
// Indique si le personnage est accroupi
privateboolisCrouched = false;
voidStart() { /***/ }
voidUpdate() {
/***/
// Si le personnage est accroupi, sa vitesse est réduite
curSpeed = isCrouched ? crouchSpeed : curSpeed;
// Le personnage ne peut pas tourner lorsqu'il est accroupi, sauf s'il se
// déplace
if (!isCrouched || axisV != 0)
transform.Rotate(Vector3.up * axisH * rotationSpeed * Time.deltaTime);
if (Input.GetKeyDown(KeyCode.Space) && isGrounded) {
rb.AddForce(Vector3.up * jumpForce);
audioSource.PlayOneShot(sfxJump);
animator.SetTrigger("Jump");
isJumping = true;
}
/***/
// Gestion de l'accroupissement : si "Shift gauche" est pressé et que "Ctrl
// gauche" n'est pas enfoncé
isCrouched =
Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.LeftControl);
animator.SetBool("IsCrouched",
isCrouched); // Déclenche l'animation d'accroupissement si
// la condition est remplie
}
/***/
}
Le système d’accroupissement est contrôlé par la touche LeftShift. Lorsqu’elle est pressée, la vitesse du personnage diminue et une animation d’accroupissement est activée.
Une fois la logique d’animation d’accroupissement en place, il est essentiel d’adapter la taille du collider pour que la détection des collisions corresponde à la nouvelle posture du personnage.
Adapter collider position accroupie
Lorsqu’un personnage change de posture, comme lorsqu’il s’accroupit, son volume occupe moins d’espace dans le monde du jeu. Pour que cela soit correctement reflété dans la physique et les collisions, il est nécessaire d’adapter la taille du collider du personnage. Cela permet de gérer les interactions avec l’environnement de manière réaliste, par exemple pour passer sous des obstacles ou pour éviter des collisions incorrectes.
Dans un jeu, la position accroupie implique une modification visuelle du personnage, mais elle doit aussi s’accompagner d’une mise à jour des éléments qui déterminent les interactions physiques, notamment le collider. Un collider mal ajusté peut causer des problèmes, comme des collisions fantômes ou un personnage qui passe à travers des objets. Il est donc essentiel de gérer la taille et la position du collider pour s’assurer que les mouvements du personnage soient aussi réalistes que possible.
Dans le présent cas, voici le problème auquel on se heurte si le personnage tente de passer en dessous d’une table
Comme vous pouvez le remarquer, le collider fait obstacle. Il faudra l’ajuster en modifiant dynamiquement la valeur des propriétés Height et Center. De même, nous allons positionner sur le modèle 3D une sphère collider à hauteur de la tête et l’utiliser comme trigger. Cela nous permettra de garder le joueur accroupie tant que ladite sphère détectera un obstacle à hauteur de la tête.
Implémentons cette logique en code :
publicclassAstraController : MonoBehaviour {
/***/
// Utilisé pour forcer l'accroupissement du personnage à travers une
// interaction avec un trigger
privateboolforceCrouched = false;
// Référence au CapsuleCollider attaché au personnage
privateCapsuleCollider capsuleCollider;
// Variables pour stocker la hauteur et le centre initial du collider
privatefloatcapsuleColliderInitialHeight;
privateVector3 capsuleColliderInitalCenter;
voidStart() {
/***/
// Récupère le CapsuleCollider du personnage et stocke ses valeurs initiales
capsuleCollider = GetComponent();
capsuleColliderInitialHeight = capsuleCollider.height;
capsuleColliderInitalCenter = capsuleCollider.center;
}
voidUpdate() {
/***/
// Vérifie si le personnage est accroupi, soit par une touche ou par une
// condition forcée
isCrouched =
Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.LeftControl) ||
forceCrouched
? true
: false;
// Met à jour le paramètre d'animation correspondant
animator.SetBool("IsCrouched", isCrouched);
if (isCrouched) {
// Réduit la hauteur du collider et ajuste le centre vers le bas lorsque
// le personnage s'accroupit
capsuleCollider.height = 1f;
Vector3 newCenter =
newVector3(capsuleCollider.center.x, 0.5f, capsuleCollider.center.z);
capsuleCollider.center = newCenter;
} else {
// Rétablit les valeurs initiales du collider lorsque le personnage se
// redresse
capsuleCollider.height = capsuleColliderInitialHeight;
capsuleCollider.center = capsuleColliderInitalCenter;
}
}
privatevoidOnTriggerStay(Collider other) {
// Forcer l'accroupissement si le personnage reste dans un trigger
// spécifique
forceCrouched = true;
}
privatevoidOnTriggerExit(Collider other) {
// Lever l'accroupissement forcé lorsque le personnage sort du trigger
forceCrouched = false;
}
}
La logique de modification du collider repose sur le fait que lorsque le personnage est accroupi (isCrouched est vrai), la hauteur du CapsuleCollider passe de sa valeur initiale à une valeur plus petite (ici 1f) et son centre est abaissé à 0.5f. Cela permet au personnage de « réduire » sa taille dans l’environnement, ce qui est crucial pour interagir correctement avec des obstacles plus bas ou se faufiler dans des espaces étroits. Lorsqu’il se redresse, les valeurs initiales du collider sont restaurées, permettant une interaction normale avec l’environnement.
Une fois que la logique d’accroupissement et d’adaptation du collider est bien établie, il est temps de réfléchir à comment adapter ce collider au saut du personnage.
Collider adapté au saut personnage
Dans les jeux en 3D, le Collider est un élément essentiel pour les interactions physiques entre le personnage et son environnement. Lorsqu’un personnage effectue un saut, le Collider doit être adapté pour correspondre à ses mouvements et maintenir des interactions réalistes avec les objets autour. Cette adaptation permet d’éviter des problèmes comme des collisions imprécises ou des comportements inattendus pendant l’animation du saut.
Le problème qui se pose ici est assez identique au précédent. Lorsque le personnage saute, son corps peut changer de posture, en particulier si l’animation de saut fait en sorte que ses jambes se plient ou que son centre de masse se modifie. Si le Collider n’est pas ajusté, il peut rester trop grand ou trop bas, ce qui entraînera des interactions physiques inappropriées, comme traverser des objets ou toucher le sol de manière incorrecte.
Pour régler le problème, nous utiliserons des courbes d’animation. Créons au préalable le paramètre de type float nommé CurveJump à initialiser à la valeur de 1.783. Vous devrez ajouter des curves du même nom ayant pour intervalle 1.783 – 1.001609 ; 0.9947327 – 1.783 respectivement pour les animations Jumping Up et Floating . Ces valeurs sont à titre indicatif dans la mesure où 1.783 représente ici la hauteur du Capsule Collider.
Nous n’avons plus qu’à ajouter l’instruction suivante dans la méthode update pour ajuster dynamiquement la hauteur du capsule collider :
void Update() {
/***/
if (isCrouched) {
/***/
} else {
/***/
}
// Si le personnage est en train de sauter, le collider est ajusté
// en fonction de la valeur récupérée d'un paramètre d'animation
// ("CurveJump").
if (isJumping)
capsuleCollider.height = animator.GetFloat("CurveJump");
}
Si le personnage saute, ce bloc de code modifie dynamiquement la hauteur du CapsuleCollider en fonction du paramètre d’animation » CurveJump « . Cela permet d’adapter le Collider à la position exacte du personnage en l’air, suivant l’animation de saut. Le paramètre « CurveJump » est probablement une courbe.
Adapter le Collider au saut d’un personnage est une étape cruciale pour garantir des interactions physiques réalistes. Cela renforce la cohérence entre les animations visuelles et les collisions. Un bon ajustement permet d’éviter des problèmes de gameplay et offre une expérience plus immersive pour le joueur.
Formez-vous gratuitement avec Alphorm !
Maîtrisez les compétences clés en IT grâce à nos formations gratuites et accélérez votre carrière dès aujourd'hui.
FAQ
Comment importer un modèle 3D dans Unity?
Comment animer la marche d'un personnage?
Comment gérer le saut du personnage?
Comment adapter le collider lors de l'accroupissement?
Comment synchroniser les sons de pas avec les animations?
Conclusion
En maîtrisant les techniques d’animation de personnages dans Unity, vous pouvez créer des expériences de jeu immersives. Quelles autres mécaniques aimeriez-vous explorer pour enrichir vos personnages de jeu vidéo?