Combat dans Godot ! | Thomas Yanuziello | Skillshare
Recherche

Vitesse de lecture


1.0x


  • 0.5x
  • 0.75x
  • 1 x (normale)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Regardez ce cours et des milliers d'autres

Bénéficiez d'un accès illimité à tous les cours
Suivez des cours enseignés par des leaders de l'industrie et des professionnels
Explorez divers sujets comme l'illustration, le graphisme, la photographie et bien d'autres

Leçons de ce cours

    • 1.

      Introduction

      1:44

    • 2.

      Configuration

      0:32

    • 3.

      Verrouillage

      15:52

    • 4.

      Strafe

      13:47

    • 5.

      Attaque

      20:46

    • 6.

      Arme

      17:20

    • 7.

      Hit

      15:43

    • 8.

      Dodge

      14:43

    • 9.

      Bloc

      15:12

    • 10.

      Séance photo

      17:43

    • 11.

      Ennemi

      15:41

  • --
  • Niveau débutant
  • Niveau intermédiaire
  • Niveau avancé
  • Tous niveaux

Généré par la communauté

Le niveau est déterminé par l'opinion majoritaire des apprenants qui ont évalué ce cours. La recommandation de l'enseignant est affichée jusqu'à ce qu'au moins 5 réponses d'apprenants soient collectées.

23

apprenants

--

projet

À propos de ce cours

Ce cours est la suite de Inventaire et des boutiques de Godot !

Cliquez sur le lien de mon site Web dans mon profil pour rejoindre notre serveur discord.

Dans ce cours, nous aborderons le verrouillage sur une cible, la motricité en mitrailleuse, l'attaque, le fait de se faire frapper, l'esquive, le blocage, le tir de projectiles et l'IA de base de l'ennemi.

Vous apprendrez également des compétences utiles pour travailler avec le moteur de jeu Godot, organiser et designer vos projets pour qu'ils soient plus évolutifs.  Vous apprendrez à coder avec GDscript, tout en expliquant les détails.  Nos scripts seront écrits pour être hautement personnalisables et réutilisables.  Tous les fichiers de projet seront également disponibles sur GitHub si vous devez revoir le projet tel qu'il était après avoir terminé chaque leçon.  Ces vidéos ont été enregistrées en utilisant la version 4.3 de Godot.

Ce cours fera partie d'une série destinée à enseigner des morceaux de développement de jeux de taille compacte qui peuvent tous être utilisés de manière interchangeable.  Faites-moi savoir quels types de jeux vous intéressent pour apprendre à créer, et j'essaierai de les inclure dans les futurs cours de cette série.

Rencontrez votre enseignant·e

Teacher Profile Image

Thomas Yanuziello

Indie Game Developer

Enseignant·e
Level: All Levels

Notes attribuées au cours

Les attentes sont-elles satisfaites ?
    Dépassées !
  • 0%
  • Oui
  • 0%
  • En partie
  • 0%
  • Pas vraiment
  • 0%

Pourquoi s'inscrire à Skillshare ?

Suivez des cours Skillshare Original primés

Chaque cours comprend de courtes leçons et des travaux pratiques

Votre abonnement soutient les enseignants Skillshare

Apprenez, où que vous soyez

Suivez des cours où que vous soyez avec l'application Skillshare. Suivez-les en streaming ou téléchargez-les pour les regarder dans l'avion, dans le métro ou tout autre endroit où vous aimez apprendre.

Transcription

1. Introduction: combat et les jeux vidéo peuvent sembler intimidants et difficiles à mettre en œuvre Ce cours vous fournira tous les outils et connaissances dont vous aurez besoin pour créer un système de combat évolutif et dynamique dans Gado Nous décomposerons le système de combat en mécanismes individuels et les combinerons pour créer un système de combat d'action robuste qui pourra être personnalisé en fonction de vos besoins. Vous apprendrez à combiner des animations de combat et de mouvement. Synchronisez les zones de frappe avec les animations d'attaque, intégrez des images oculaires dans les animations d'esquive, bloquez les ennemis. Lancez des projectiles avec une arme arrangée et contrôlez les ennemis à l'aide de scripts d'IA Si vous avez besoin d'aide, notre serveur Discord regorge d' autres étudiants et développeurs de jeux qui peuvent répondre à toutes vos questions Cliquez sur le lien du site Web dans mon profil pour m'inscrire. J'utiliserai un projet de démarrage créé dans la version 4.3 de God qui est disponible sur mon GitHub en utilisant des ressources gratuites provenant de ce point IO Mais vous pouvez suivre votre propre projet en utilisant différents actifs. Pour tirer le meilleur parti de ce cours, vous aurez besoin d'une scène dans votre projet avec un personnage que le joueur peut contrôler et au moins un ennemi. Vous pouvez également avoir besoin d'un système d' inventaire et d'équipement capable d'équiper les personnages d'une arme et d'un bouclier Pour plus d'informations sur ces sujets, consultez mon cours précédent. Le combat ne doit pas nécessairement être une bataille ardue. Dégainons nos armes et battons-nous ensemble. 2. Configuration: Bonjour, mes amis. Avant de commencer, vous devriez avoir un projet avec un personnage capable se déplacer dans un environnement et des ennemis à combattre. Vous pouvez également avoir besoin d'un menu d'inventaire capable d'équiper des objets, y compris au moins une arme mala, une arme arrangée et un bouclier Tout au long de ce cours, nous ajouterons des commandes, des mécanismes et des animations à notre projet pour fixer une cible, attaquer, esquiver, bloquer et tirer des projectiles 3. Verrouillage: Pour notre première leçon, nous allons permettre au joueur de s'accrocher à un ennemi. Commençons par ajouter un mappage d'entrée pour activer le verrou Ouvrez les paramètres du projet, passez à l'onglet de la carte d'entrée. Nous pouvons ajouter un événement d'entrée nommé Toggle Lock. faisant défiler l'écran vers le bas pour trouver le nouvel événement d'entrée, je vais associer la touche Q clavier et le joystick droit ma manette à cet Dans le script de gestion des entrées du joueur, nous aurons besoin de références au personnage, au bras à ressort et à la caméra, tout configuré avec Add-on Ready. Pendant la fonction de saisie, après avoir vérifié l'absence de pause, ouvert ou fermé le menu d'inventaire et si le contrôle du joueur a été désactivé. J'ai divisé le reste des entrées entre les caméra et les commandes de personnage pour une meilleure organisation. Actuellement, la seule commande de caméra consiste faire pivoter le bras à ressort qui maintient la caméra à l'aide de la souris. Vérifions également si le bouton de verrouillage a été enfoncé. Il s'agira d'une entrée contextuelle avec plusieurs fonctions possibles. Nous devons savoir si le joueur est actuellement bloqué sur une cible. Déclarons donc une variable contenant cible actuellement verrouillée sous la forme d'un nœud en trois D, sorte que n'importe quel objet en trois D notre monde de jeu pourrait potentiellement être verrouillé. Nous pouvons d'abord diviser les fonctions du bouton de verrouillage en deux catégories possibles, si la valeur de la cible est nulle ou non, que nous pouvons raccourcir en deux catégories simples Commençons par le bloc s où le joueur n'est actuellement bloqué sur rien. Ici, nous devrons attribuer à la cible la valeur la plus proche de la cible visible, et nous pouvons déléguer la responsabilité de déterminer quelle est la cible visible la plus proche de la caméra Dans le cas où aucune cible visible n'est la plus proche, la cible sera toujours nulle. Dans de nombreux jeux d'action-aventure, lorsque vous appuyez sur le bouton de verrouillage, il n'y a rien à verrouiller. La caméra se réinitialise ensuite pour se placer derrière le personnage du joueur, ce qui sera fonction du bras à ressort Si le joueur est déjà bloqué sur une cible et qu' il appuie sur le bouton de verrouillage, plusieurs cas doivent également être pris en compte. S'il y a plusieurs cibles visibles, le joueur se fixe sur cible visible la plus proche, plus de celle sur laquelle il est actuellement bloqué Nous pouvons réutiliser la même fonction de la caméra pour trouver la cible la plus proche Mais cette fois, fournissez également la cible actuelle comme argument, et nous allons écrire l'algorithme pour ignorer cette cible. Dans le cas ci-dessous, nous pouvons toujours dépasser la cible actuelle puisque sa valeur est nulle, nous n'aurons donc rien à ignorer. S'il n'y a pas plusieurs cibles visibles, cette fonction renverra également null et le verrouillage sera désactivé. Qu' il y ait ou non plusieurs cibles, si le joueur appuie également sur le bouton enfoncé, la plupart des jeux désactiveront le verrouillage dans ce cas Nous pouvons déterminer si la direction d'entrée donnée est similaire à celle du bas en utilisant un produit scalaire des deux vecteurs et en vérifiant si elle est supérieure à 0,75 Cela couvrira toutes les directions proches du bas, mais n'atteindra pas les diagonales. Nous voulons avoir la possibilité de désactiver le verrou depuis l'extérieur du script, il serait donc judicieux d'en faire une fonction publique Appelons-le toggle lock et donnons-lui un paramètre optionnel pour forcer verrouillage avec une valeur par défaut false La valeur de la cible sera définie sur null si elle est forcée. Sinon, il peut être réglé sur cible visible la plus proche, telle que déterminée par la caméra, ignorant la cible actuelle s'il y en a une. les trois cas ci-dessus, il est désormais possible d' appeler Toggle lock , il suffit spécifier que le verrouillage est activé dans le cas où la direction de saisie vers le bas est également indiquée, et d'autres scripts peuvent également obliger le joueur à le verrouiller pour une raison ou une autre Passage au script Spring Arm. Supposons que le joueur appuie sur le bouton de verrouillage, mais qu'aucune cible ne soit visible Nous voulons que le bras à ressort positionne la caméra derrière le personnage. Nous aurons donc besoin d'une référence au personnage auquel le bras à ressort est attaché, qui dans mon cas sera toujours le nœud parent du bras à ressort. Si vous utilisez une structure de nœud différente, vous pouvez plutôt exporter cette variable et définir sa valeur dans le panneau de l'inspecteur. Pour faire pivoter progressivement la caméra derrière le personnage au fil du temps, nous utiliserons une variable d'interpolation de type tween Il serait judicieux d'exporter une variable correspondant à la durée de l'interpolation J'utiliserai un quart de seconde. Nous pouvons également avoir besoin d'une valeur pour la rotation x préférée afin de réinitialiser la rotation des bras du ressort à deux. J'utiliserai 0,5 radian négatif, en positionnant la caméra légèrement au-dessus du personnage, en regardant vers l' avant et légèrement vers le bas selon un angle Déclarons également une variable pour conserver la rotation cible de l'interpolation sous forme de vecteur trois et initialisons-la en tant que vecteur trois avec la rotation x réinitialisée comme valeur x, mais zéro pour les rotations y et z. donnant une définition à la fonction, nous pouvons également accepter un paramètre facultatif pour la durée de l'interpolation en l'utilisant comme valeur par défaut afin qu'il puisse être remplacé Pour faire pivoter la caméra derrière le personnage, nous pouvons faire appel à une nouvelle fonction privée pour ajuster la rotation des bras du ressort Spécifier que nous voulons que la rotation y soit la rotation des personnages plus une demi-rotation représentée par Pi radians Écrivons ensuite la fonction privée qui interrompt la rotation des bras du ressort, en acceptant une rotation cible en tant que valeur flottante, ainsi qu'une durée pour l' interpolation acceptant une rotation cible en tant que valeur flottante, ainsi qu'une durée pour l' interpolation avec une valeur par défaut de la durée exportée Nous allons commencer par définir la propriété y de la rotation cible comme étant la rotation y cible acceptée en tant que paramètre. Mais pour que la rotation emprunte toujours le chemin le plus court autour du personnage, nous devons placer sa valeur de manière à ce qu'elle soit toujours comprise entre le point de rotation actuel y moins une demi-rotation et le point de rotation actuel y plus une demi-rotation. Si un préadolescent existe déjà et est en cours d'exécution, nous devons le tuer avant d'en créer un nouveau Nous pouvons ensuite adapter la rotation des bras du ressort à la rotation cible sur la durée Laissons ensuite la caméra détecter les cibles visibles. Ma caméra n'a pas encore de comportement scripté, alors ajoutons un nouveau script et placons-le dans le dossier des scripts des joueurs Nous aurons besoin d'une fonction publique pour obtenir la cible visible la plus proche, acceptant un paramètre facultatif de la cible actuelle avec une valeur par défaut nulle, afin que nous puissions éventuellement l'ignorer. Cela renverra un nœud en trois D, et le cas par défaut sera de renvoyer null si nous ne trouvons pas de cible visible. Afin de déterminer laquelle des cibles visibles est la plus proche, nous devons conserver une liste de toutes les cibles visibles. Déclarons une autre variable contenant toutes les cibles visibles sous la forme d'un tableau de nœuds à trois D. Initialisé pour être vide. Un moyen simple de savoir quelles cibles sont visibles est d'attacher un nœud de zone 3D à la caméra. Appelons cela la plage cible. Cette zone surveillera tout ce qui se trouve dans la couche de collision 11, que j'ai choisie pour représenter les ennemis. Assurez-vous que la couche de collision de vos ennemis est définie sur la même couche que celle masquée par le verrou lors du ciblage Je devrai également réinitialiser les zones transformées pour la positionner à l'origine de la caméra. Le nœud de la zone trois D a besoin d'une forme de collision, et nous pouvons remplir la ressource de forme avec un polygone convexe À l'aide d'un polygone convexe, nous pouvons définir la forme sous la forme d'une pyramide, qui copie exactement le champ de vision de la caméra, mais avec une portée limitée Comme le champ de vision de la caméra prendra la forme d' une pyramide à quatre côtés, nous pouvons le définir avec cinq points le premier point étant identique à la position de la caméra. Les quatre autres seront positionnés le long de l'axe Z, la distance maximale de notre portée de verrouillage. J'utiliserai une distance maximale de 15 mètres. Passant à la vue orthogonale supérieure et masquant l' environnement pendant un moment, je vais simplement ajuster rapidement la position de chaque point de la pyramide pour qu'elle corresponde approximativement au champ de vision de la caméra, 11,4 mètres à gauche et à De même, en vue orthogonale à gauche, ajustant les valeurs y des points de la pyramide, 6,4 mètres vers le haut et vers Jusqu'à ce que nous ayons une forme de pyramide, correspondant au champ de vision de la caméra, qui atteint 15 mètres. Je reviendrai ensuite à la vue en perspective et reparlerai de la visibilité de l'environnement. Chaque fois qu'un corps entre dans cette zone, reliant le signal saisi par le corps au script de la caméra, nous pouvons ajouter le corps à notre gamme de cibles visibles De même, chaque fois qu'un corps sort de cette zone, il peut être effacé de la matrice Tout corps de collision en trois D sur la couche 11, qui existe à l'intérieur de cette zone sera désormais considéré comme une cible visible. Dans mon script Spring Arm, j'aurai besoin de n'importe quelle balise pour utiliser la fonction get parent. lançant le jeu et en passant à l'arborescence des scènes distantes, nous pouvons sélectionner la caméra et afficher ses propriétés dans l'inspecteur, y compris le tableau des cibles visibles. Au fur et à mesure que la caméra se déplace sur la scène, le tableau des cibles visibles se met à jour automatiquement pour ajouter et supprimer chaque ennemi lorsqu'il entre dans le champ de vision ou en sort. Appuyez sur le bouton de verrouillage ne rien cibler pour l'instant, mais nous pouvons voir comment cela repositionne la caméra derrière le personnage Avant d'autoriser le verrouillage d'une cible, nous pouvons également vérifier si la ligne de visée du joueur par rapport à la cible est obstruée par le terrain Ajoutons également un nœud Ray Cast Three D à la caméra et nommons-le ligne de visée. Ensuite, saisissez-en une référence dans le script de la caméra. Pour trouver la cible visible la plus proche avec notre caméra, si le réseau est vide, sa taille est nulle, alors il n'y a aucune cible visible à prendre en compte, et nous devons simplement revenir. S'il y a des cibles visibles à prendre en compte, nous devrons comparer les distances de chacune par rapport à la caméra pour trouver celle qui est la plus proche. Pour ce faire, nous avons besoin d'une variable pour maintenir à la distance entre la cible actuelle flot la distance entre la cible actuelle et la caméra La distance la plus proche à flot et l'indice de la cible visible la plus proche sous forme Nous allons définir la distance la plus proche sur infinie en utilisant le mot clé I NF, et l'indice le plus proche sur moins un pour indiquer qu'il ne s'agit pas d' un index pas d' un Si, après avoir itéré l'ensemble du tableau de cibles visibles, l'indice le plus proche est toujours négatif, alors aucune cible visible n' a été considérée comme valide et nous devons renvoyer la valeur null Sinon, nous pouvons renvoyer la cible visible à l'index le plus proche. Si la cible visible à l'indice I est la cible actuelle, nous pouvons l'ignorer avec la déclaration continue. Pour toute autre cible visible, nous devrons calculer sa distance par rapport à la caméra. Nous pouvons utiliser la distance au carré car c'est mathématiquement plus efficace Si la distance actuelle est inférieure à la distance la plus proche, nous devrons vérifier si la ligne de visée de cette cible est obstruée abord, nous devons réinitialiser Tout d'abord, nous devons réinitialiser la rotation actuelle de la ligne de visée. Réglez ensuite la position cible du rayon diffusé sur la position globale de la cible moins la position globale de la caméra et forcez la mise à jour. Mais la position des personnages est généralement au sol, ce qui est facilement obstrué par de petits bouts de terrain et n'est pas toujours un bon indicateur de la ligne de visée Ajoutons également 1 mètre. Si la ligne de visée entre en collision avec quelque chose et que cet objet est la cible visible, alors la ligne de visée n'est obstruée par rien, ce qui fait de cette cible la cible visible la plus proche que nous ayons trouvée jusqu' Nous pouvons définir la distance la plus proche par rapport à la distance actuelle et l'indice le plus proche I avant de passer au reste du tableau Cela renverra désormais la valeur nulle ou la cible visible la plus proche de la caméra La ligne de visée entrera également en collision avec la couche 11, à la recherche d'ennemis, mais aussi couche 1 qui sera obstruée par Il serait également intéressant de faire savoir au joueur sur quoi il est bloqué grâce à l'indicateur de cible. Ajoutons un nœud Sprite Three D en tant qu'enfant du gestionnaire de saisie du joueur et renommons-le Pour la texture, je vais utiliser le pointeur vide de la barre de défilement. Mais modifiez ses paramètres de saisie pour activer Alpha prémultiplié afin de le rendre un peu plus fluide Et réduisez-le au quart de sa taille. Ensuite, en élargissant la section drapeau, je vais activer son drapeau d'affichage, afin qu'il soit toujours face à la caméra Et le drapeau de test sans profondeur attirera toujours le sprite au-dessus tout le reste, quelle que soit sa position dans l'espace tridimensionnel par rapport à la caméra L'indicateur de cible peut être invisible par défaut puisque le joueur démarre sans cible à indiquer. Saisir une référence à l'indicateur cible en utilisant Add on ready Nous devrons ensuite le positionner au-dessus de la cible verrouillée. Donc, après avoir déterminé sur quoi le joueur est bloqué, s' il y a une cible. Un moyen simple de faire en sorte que l'indicateur cible suive la cible est de le réparer en fonction de cette cible. Nous pouvons ensuite le déplacer de quelques mètres vers le haut pour le positionner au-dessus la tête de la cible et définir sa propriété visible sur true. S'il n'y a aucune cible à indiquer, nous pouvons réparer l'indicateur sur ce nœud et redéfinir sa propriété de visibilité sur falls pour le masquer. Essayons-le. Lorsque nous appuyons sur le bouton de verrouillage, l'ennemi le plus proche est ciblé et l'indicateur est positionné au-dessus de la tête de la cible En appuyant à nouveau sur le bouton de verrouillage, passez à l'ennemi le plus proche Maintenez le bouton de verrouillage enfoncé et appuyez dessus pour désactiver le verrouillage. S'il n'y a qu' une seule cible visible sur laquelle nous sommes déjà verrouillés, verrouillage est également désactivé. Dans notre jeu, le joueur se concentre désormais sur ses ennemis. Dans la leçon suivante, nous allons modifier le comportement de l'appareil photo et du personnage lorsqu'il est verrouillé. Je te verrai dans la prochaine leçon. 4. Strafe: Bonjour, mes amis. Dans la leçon précédente, nous avons ajouté un bouton de verrouillage contextuel à notre jeu Dans cette leçon, nous allons modifier le comportement des nœuds du joueur lorsqu'ils se bloquent sur une cible. À partir du script du lecteur, une fois qu'une cible a été verrouillée, émettons un signal afin que tout autre script puisse écouter et réagir à la modification de la valeur de la cible, en spécifiant ce qui était ciblé en tant que paramètre. À l'aide d'un setter, nous pouvons émettre le signal chaque fois que la valeur de la cible est modifiée pour une raison quelconque Désormais, le personnage, le bras à ressort et la caméra peuvent se connecter au signal l'utiliser pour définir leurs propres variables privées pour ce qui est ciblé. Quelle que soit la valeur de target dans le script de gestion des entrées du joueur, tous les autres nœuds auront également les mêmes informations, y compris s'ils sont définis sur null. Écrire une fonction simple pour chacun qui définit une variable cible locale afin qu'ils puissent tous y accéder facilement. Une fois que notre personnage s' est fixé sur une cible, nous nous attendons à ce qu'il fasse face à la cible au lieu de faire face dans la direction dans laquelle il se déplace. Dans mon script, la rotation du personnage s'effectue selon un processus physique, qui indique au personnage de faire face dans la direction dans laquelle le mouvement est entré. Déclarons une nouvelle variable en haut du script, qui veut faire face à la direction sous la forme d'un trois. Et remplacez la direction d'entrée par want to face direction dans l'appel de fonction. Ensuite, avant cet appel de fonction, nous pouvons vérifier si le personnage est verrouillé sur une cible. S'ils sont attachés à une cible, la direction à laquelle ils voudront faire face sera vers la cible, faire face sera vers la cible, ce que nous pouvons facilement déterminer en soustrayant leurs positions globales S'ils ne sont pas verrouillés, ils voudront faire face à la direction de saisie du mouvement, comme c'était le cas auparavant. Maintenant, le personnage fait face à la cible bloquée, mais ses animations locales ne sont pas très belles, car elles se mélangent uniquement en fonction de la vitesse à laquelle le personnage se déplace et non en fonction de la direction Dans la machine à états de l' arbre d'animation du personnage, ils sont en état d'inactivité car il n'y a pas de plancher dans la scène. L'état de mouvement de la locomotive est un espace de mélange unidimensionnel, mêlant les animations de marche au ralenti et de course en fonction de la vitesse de déplacement du personnage Supprimons cet état et remplaçons-le par une autre machine à états. Reconnecter les transitions aux autres états, commençant par une transition entre le début locomotion pour en faire l'état par défaut La transition vers le démarrage par saut a été activée avec un poids transversal de 0,3 seconde. Et sautez de la terre ferme à la locomotion en changeant à la fin avec un destin croisé de 0,67 seconde Je vais omettre la transition entre la locomotion et l' inactivité temporaire lorsque je travaille dans la machine de locomotion, afin que le personnage reste dans l'état de locomotion et que je puisse voir les résultats Appuyez sur le bouton de jeu pour forcer le personnage se déplacer et il se lancera car il est actuellement vide Dans l'état de locomotion, nous aurons besoin de deux séries différentes d'animations de locomotion, à savoir lorsque le personnage est bloqué sur une cible et lorsqu'il ne l'est pas, et pour pouvoir passer de l'une à l' La valeur par défaut sera la même qu'avant, un espace blond unidimensionnel. Disons qu'il n'est pas verrouillé. Ensuite, nous pouvons également ajouter un espace blond bidimensionnel. Appelons celui-ci verrouillé. L'ajout d'une transition entre le mode de démarrage le mode non verrouillé fait de celle-ci la transition par défaut. Nous pouvons ensuite passer de « non verrouillé » à verrouillé » si la valeur de la cible n'est pas nulle, nous pouvons la raccourcir pour n'en faire que cible et lui donner un court fondu croisé. Et revenez à la cible non verrouillée, sinon à la cible avec le même fondu croisé. À l'intérieur de l'espace de mélange non verrouillé. Nous pouvons le recréer exactement comme avant, avec une valeur minimale de zéro en mélangeant des animations de ralenti, de marche et de course en fonction de la vitesse de déplacement du personnage fois cela fait, utilisez les miettes de pain pour monter d'un niveau jusqu'à la machine de locomotion et appuyez sur le bouton de jeu la machine verrouillée pour forcer le personnage à entrer dans cet état pour forcer le personnage à entrer dans cet Dans l'espace de mixage verrouillé , nous allons fusionner les animations en fonction la direction dans laquelle le personnage se déplace par rapport à sa direction avant, c'est-à-dire vers sa cible. Je vais régler le quadrillage par incréments d'un pour faciliter les choses Si nous positionnons notre champ de vision derrière le personnage et imaginons qu'il est bloqué sur une cible devant lui, axe y représente la vitesse à laquelle le personnage se rapproche ou s'éloigne de la cible. L'axe X représente la vitesse à laquelle le personnage se déplace vers la gauche ou vers la droite contourner la cible Commençons par placer l'animation inactive au milieu. Pour l'axe X, nous allons placer une animation de mitraillage gauche sur le côté gauche et une animation le côté gauche et une mitraillage droit sur le côté droit Pour l'axe y, nous pouvons placer une animation en cours en position avant, ce qui générera des triangles dans l'espace de fusion indiquant comment les différentes animations seront fusionnées Et en ajoutant une animation de marche en arrière en position Y négative, nous ajouterons également d'autres triangles Si nous changeons la position de fusion, nous pouvons voir à quoi ressemblera le personnage tout en donnant une entrée de mouvement dans n'importe quelle direction. En fonction des ressources que vous utilisez, vous pouvez également avoir des animations de mouvements en diagonale à ajouter à cet espace de fusion. Parfois, cet aperçu ne simule pas exactement le comportement du personnage pendant le jeu. Et vous devriez toujours le tester en jouant au jeu pour vous assurer qu'il s' intègre bien dans le jeu. Mais avant cela, revenons à la base de la machine étatique et ajoutons la transition entre la locomotion et le saut au ralenti, à condition que le personnage ne soit pas au sol J'avais l'habitude de franchir le temps de fondu de 0,3 seconde pour cette transition. Nous devons également mettre à jour la partie de notre script qui définit la position de fusion de l'espace de fusion, ce qui, dans le script de mon personnage se produit dans le cadre de la physique du sol. En sélectionnant l'arbre d'animation, nous pouvons copier le chemin de propriété de la position non verrouillée lors du mélange et le mettre à jour dans la fonction set. Mais cela ne doit être défini que si le personnage n'est pas attaché à une cible. S'ils sont verrouillés sur une cible, nous devrons plutôt définir la position de fusion de l'espace de fusion verrouillé. La position de fusion bloquée est un vecteur deux avec un x et un y , que nous devrons calculer. Déclarons donc une variable pour la conserver nommée locked on blend. Pour éviter de répéter les mêmes calculs plusieurs fois, je vais également déclarer une autre variable pour stocker la vélocité relative du personnage, qui sera sa vélocité x z divisée par sa vitesse de course. Après avoir calculé cette valeur, la position de fusion de l'espace de fusion non verrouillé peut être réglée sur la longueur de ce vecteur. Si le personnage est bloqué sur une cible, nous pouvons trouver la valeur x de la position de mélange en utilisant le produit scalaire du vecteur de base global x des plates-formes avec leur vitesse relative Le produit scalaire de deux vecteurs donne un nombre représentant leur similitude ou leur différence. Nous vérifions donc dans quelle mesure la vitesse relative du personnage est similaire la vitesse relative du personnage est à celle d'un vecteur pointant directement vers sa droite. En fonction de la configuration de votre personnage la direction considérée comme allant vers l'avant, vous devrez peut-être multiplier cette valeur par moins un pour l'inverser. La position du mélange y peut également être déterminée en utilisant la même méthode, mais en utilisant le vecteur z avant du personnage. Ensuite, lorsqu'elle est verrouillée sur une cible, la caméra doit regarder la cible, et non le personnage du joueur. Dans la fonction de traitement de la caméra, ignorant Delta, s' il y a une cible, nous pouvons dire à la caméra de regarder la cible et ajouter 1 mètre pour ne pas regarder ses pieds. Lorsque vous définissez la valeur de la cible, si la cible est définie sur zéro, nous pouvons réinitialiser la rotation de la caméra pour revenir à la même valeur que son nœud parent, le bras à ressort, en réglant sa rotation sur le vecteur 30 Nous pouvons également vouloir déclencher la fonction de verrouillage si la cible actuelle sort de notre limite de portée visible Ether se verrouille ou passe automatiquement à une cible plus proche. Ajoutons donc un signal indiquant quand la cible actuelle sort de portée et émettons-le si le corps qui a quitté la zone est la cible actuelle Nous pouvons ensuite connecter ce signal au script de gestion des entrées du lecteur. Appel de la fonction Toggle Lock. Selon que vous souhaitez que le comportement passe à la cible la plus proche ou qu'il soit simplement bloqué, vous souhaiterez peut-être lier un argument vrai pour la force du paramètre. Dans le script Spring Arm, lorsque vous êtes bloqué sur une cible, nous voulons que le bras à ressort pointe toujours dans le sens opposé à la cible afin de garder la cible et le personnage du joueur dans le champ de vision de la caméra. Ajoutons une nouvelle variable pour conserver cette direction sous forme de vecteur trois. Ensuite, lorsque la valeur de la cible est définie, si elle n'est pas nulle, nous pouvons définir la valeur de la direction de la cible comme étant définie, si elle n'est pas nulle, nous pouvons définir la valeur de la direction de la différence entre notre position globale moins la position globale de la cible. Cela se traduira par un vecteur pointant de la cible vers le personnage du joueur. Nous pouvons ensuite réutiliser la fonction de rotation entre deux, mais elle attend un paramètre float représentant une rotation y. Nous pouvons obtenir la rotation y, qui pointera dans cette direction utilisant la fonction trigonométrique A t deux, en lui donnant les valeurs x et z de notre Une fois la cible définie, le bras à ressort fait tourner la caméra dans la direction opposée à celle de la cible située derrière le joueur. Mais nous voulons qu'il y reste. Dans la fonction de traitement, si la valeur de la cible a été définie et entre parenthèses, si l'interpolation n' existe pas ou n'est pas en cours, ce qui signifie que l'interpolation est terminée et que le bras du ressort est en position, nous pouvons effectuer les mêmes calculs, mais simplement régler la valeur de rotation y directement au lieu de faire un autre ce qui signifie que l'interpolation est terminée et que le bras du ressort est en position, nous pouvons effectuer les mêmes calculs, mais simplement régler la valeur de rotation y directement au lieu de faire Cela permet de maintenir le bras à ressort dirigé à l'opposé de la cible, tout en maintenant la cible et le personnage du joueur dans le champ de vision de la caméra. Enfin, dans le script de gestion des entrées du joueur, nous voulons empêcher le joueur de pivoter le bras à ressort lorsqu'il est bloqué sur une cible. Cela se produit à deux endroits différents dans mon script, l'un pour les commandes sur PC à l'aide de la souris, et l'autre pour le support de la manette avec le joystick droit. Je vais donc simplement intégrer les deux dans une instruction if pour ne pas autoriser ces entrées lorsque je suis verrouillé sur une cible. Essayons-le. Lorsque nous nous accrochons à un ennemi, la caméra se concentre sur la cible, tandis que le bras à ressort tourne pour positionner la caméra dans la direction opposée En déplaçant le personnage, ils pivotent pour faire face à l'ennemi et animent des mouvements fluides dans toutes les directions Le bras à ressort maintient la position de la caméra, qui se trouve derrière le personnage , en direction opposée à la cible, tandis que la caméra continue de regarder la cible. Les commandes normales de l' appareil photo du joueur ont été désactivées lorsqu'il est verrouillé. Si la cible verrouillée est hors de portée, elle passe automatiquement à cible la plus proche ou se verrouille s'il n'y en a pas une sur laquelle se verrouiller. Si nous forçons le verrouillage, la caméra se recentre sur le personnage du joueur, contrôle normal du bras à ressort reprend et les animations de locomotion du personnage redeviennent Nos nœuds de joueurs adaptent désormais leurs comportements au verrouillage d'une cible. Dans la leçon suivante, le personnage du joueur va exécuter des attaques. Je te verrai dans la prochaine leçon. 5. Attaque: Bonjour, mes amis. Dans la leçon précédente, nous avons modifié le comportement des nœuds du joueur lorsqu'ils sont verrouillés sur une cible. Dans cette leçon, nous allons ajouter des animations d'attaque afin que les personnages puissent s' attaquer les uns les autres. Commençons par ouvrir les paramètres du projet, l'onglet de saisie de la carte, et ajouter un nouvel événement d'entrée pour attaquer. Je vais utiliser le bouton gauche de la souris et le bouton droit de l'épaule de ma manette. Ensuite, dans le script du gestionnaire de saisie du joueur, nous pouvons vérifier si le bouton d' attaque a été enfoncé lors de la vérification des entrées de contrôle des personnages Si le bouton d'attaque a été enfoncé dans cette image, alors nous devrions dire au personnage d'attaquer. Mais que faire si le personnage est occupé ? Ils peuvent sauter ou effectuer une autre action et nous ne voulons peut-être pas qu'ils soient capables d'attaquer en ce moment. Exiger du joueur qu'il attende qu'il soit possible d'attaquer avant d' appuyer sur le bouton serait très frustrant. La plupart des jeux modernes considèrent que le fait d'appuyer sur le bouton est valide pendant une courte période après l'avoir enfoncé, ce que l'on appelle la mise en mémoire tampon des entrées Ajoutons une heure ou un nœud au gestionnaire des entrées du joueur. Nommez-le tampon d'entrée et définissez sa propriété one shot sur true, afin qu'il ne compte à rebours qu'une seule fois à la fois. saisissant une référence à ce temporisateur de la mémoire tampon d'entrée en utilisant Add on Ready, nous pouvons démarrer le chronomètre après avoir demandé au personnage d'attaquer, puis attendre son signal d'expiration Une fois que le compte à rebours aura été compté jusqu'à zéro, nous demanderons au personnage d' annuler l'ordre d'attaque qui lui a été donné. Ainsi, à tout moment pendant le compte à rebours, le personnage essaiera d' attaquer lorsqu'il sera prêt. Le temps d'attente par défaut pour le temporisateur est de 1 seconde, ce qui est une durée raisonnable pour la mémoire tampon d'entrée de l'attaque. Une autre entrée que nous pourrions vouloir mettre en mémoire tampon est l'entrée de saut. suivant le même schéma que l'entrée d'attaque, nous pouvons démarrer le chronomètre, attendre son signal d'expiration, puis annuler l'entrée de saut. Dans le script du personnage, commençons par créer une nouvelle région de code pour le combat. Déplacez ensuite la fonction ciblée par le joueur dans cette région. Nous aurons besoin d'une fonction publique pour demander au personnage d' attaquer et d'une autre pour lui demander d'annuler l'instruction. La fonction de saut aura également besoin d' une correspondance et d'une fonction de saut d'annulation deux. L'objectif principal de ces fonctions est de définir des variables qui seront vérifiées par l'arbre d'animation afin qu'il sache vers quels états se déplacer. En haut du script, nous ajouterons d'autres variables pour indiquer les intentions du personnage quant à ce qu'il veut faire ensuite entrées en mémoire tampon sous forme de booléens, s'il veut sauter ou attaquer Ensuite, la fonction d'attaque définira la variable want to attack sur true et annulera l'attaque la remettra sur false. Comme les entrées sont mises en mémoire tampon, nous n'avons plus besoin d'exiger que le personnage soit capable de se déplacer ou d'être au sol, et nous pouvons déléguer cette responsabilité à la machine d'état des arbres d'animation De plus, nous n'avons pas besoin de demander à la machine d' état de l'arbre d'animation de passer à l'état de démarrage rapide. Nous rendrons cette transition automatique si les conditions sont remplies. Mais nous ne voulons pas que ces deux variables soient vraies en même temps. Le personnage voudra soit sauter, soit attaquer, pas les deux. Ainsi, chaque fois qu'une entrée mise en mémoire tampon est définie sur true, toutes les autres sont définies sur false, annulant ainsi l'instruction Dans la scène du personnage, en sélectionnant l'arbre d'animation et passant au panneau de l'arbre d'animation, nous pouvons voir la machine à états. Faisons en sorte que la transition entre la locomotion et le démarrage soit automatique à condition que le personnage soit au sol, qu'il puisse se déplacer et qu'il veuille sauter Désormais, le personnage sautera automatiquement dès qu' il en capable dans la seconde qui suit l' appui sur le bouton de saut. Ceci est particulièrement utile pour enchaîner les sauts les uns après les autres, puisque le joueur pourra appuyer sur le bouton de saut avant de toucher le sol Mais en ce qui concerne la machine à états de saut, voyons comment intégrer les animations d'attaque. Nous pourrions passer de la locomotion à l' attaque et vice versa. Mais les animations seraient mauvaises si nous voulions que le personnage puisse se déplacer tout en attaquant. Je n'autoriserais pas le personnage à attaquer en sautant. Il serait préférable de séparer les animations impliquant le déplacement du personnage de celles impliquant l' exécution d'actions. Si votre machine à états n'a pas encore été enregistrée en tant que ressource de projet, cliquez sur le menu déroulant à côté Tree Root et sélectionnez Enregistrer sous. J'ai déjà enregistré le mien dans le dossier des scènes de personnages et je l'ai nommé animations de personnages. Mais je vais le renommer en mouvements de personnage. fois la machine à états enregistrée, retirons-la de l'arbre d'animation du personnage et remplacons-la par un arbre de fusion de nœuds d'animation. Le panneau de l'arbre d'animation affiche désormais un graphique qui contient notre arbre de fusion, ce qui nous permet de fusionner autant d' animations que vous le souhaitez. Cliquez avec le bouton droit de la souris dans un espace vide, puis sélectionnez Charger. Parcourez ensuite les ressources de votre projet pour trouver la machine à états de mouvement de votre personnage. La machine à états que nous utilisions précédemment est désormais un nœud dans le graphe de l'arbre de fusion, et le résultat de la machine à états sera affiché par la broche située sur le côté droit. Si nous connectons la sortie de la machine à états à la sortie de l'arbre de fusion, l'animation fonctionnera comme avant. Mais le but de l'arbre de fusion est de fusionner plusieurs animations. Débranchons la broche. Cliquez ensuite avec le bouton droit de la souris et ajoutez un nœud de fusion à deux. Le nœud de fusion commence par l'animation connectée à sa broche d'entrée et intègre un pourcentage de l'animation connectée à sa broche d'entrée de fusion. Le résultat de ce mélange sera affiché par la broche située sur le côté droit, que nous pouvons connecter à la sortie des arbres de mélange. L'animation que nous voulons intégrer aux mouvements du personnage sera celle des actions du personnage, à savoir ses attaques. Nous pouvons ajouter une autre machine à états à l'arbre de mélange et la nommer action. Connectez ensuite sa sortie à la broche d'entrée du mélange à deux nœuds. Ensuite, nous allons ouvrir la machine à états d'action et lancer le personnage dans l'animation inactive. Passer de l'état de démarrage à l' inactif pour en faire l'état d'action par défaut Ensuite, nous aurons besoin d'une vue de notre personnage et de démarrer les machines à états de mouvement et d'action en cliquant sur le bouton de jeu situé dans leur état de départ respectif. Retournez ensuite à la racine de l'arbre de mélange. Notre personnage semble toujours dans l' animation « jump idle » car le pourcentage de l'animation d'action qui y est intégrée est actuellement nul Si nous faisons glisser la poignée sur un, nous pouvons voir l'animation passer progressivement du mode «   jump idle » au « idle ». Cliquez ensuite sur le bouton Modifier les filtres, puis activez l'activation du filtrage. Déplaçons la fenêtre pour que nous puissions voir notre personnage tandis que nous filtrons les os individuels, décidant à quels os nos animations d'action doivent être appliquées et à quels os elles ne doivent pas être appliquées. Activez tous les os qui constituent le haut du corps du personnage. Désormais, le bas du corps du personnage, y compris sa position, est affecté par l'état de mouvement. Sautez au ralenti, tandis que le haut de leur corps est contrôlé par leur état d'action inactif. Cela nous permet de combiner ces animations de trois manières différentes. Si le personnage se déplace mais n'effectue aucune action, montant du mélange sera nul, en utilisant uniquement la sortie de la machine à états de mouvement. Si le personnage exécute une action mais ne bouge pas, montant du mélange sera égal à un et les filtres désactivés, en utilisant uniquement le résultat de la machine à états d'action. Si le personnage se déplace et exécute une action, les filtres seront activés. Utilisation de la sortie de la machine à états de mouvement pour le bas du corps du personnage et la sortie de la machine à états d'action pour le haut du corps. Nommons ce mélange de deux nœuds inférieur et supérieur, car il mélange les animations du haut du corps avec les animations du bas du corps Mais si le montant du mélange est égal à zéro ou à un, les animations de l'une des machines à états ne seront pas exécutées pour économiser du temps de traitement, ce qui peut entraîner des problèmes si nous nous appuyons sur elles pour définir les propriétés ou appeler des méthodes. Il peut être utile de toujours faire fonctionner les deux machines à états en permanence, même si le personnage n' effectue aucune action ou ne bouge pas. Pour garantir que les deux machines à états sont toujours actives, nous pouvons définir le montant du mélange à 1 % et, lorsque vous effectuez une action, l' augmenter à 99 %. Nous pouvons supposer qu'il devrait commencer par un mélange de 1 % car le personnage n' effectuera aucune action lors du premier chargement. en revenir au script du personnage, étant donné que l'arbre d'animation va devenir beaucoup plus complexe, il serait judicieux d' abstraire ses comportements dans son propre script. Nous pouvons supprimer la variable de lecture State Machine du script de personnage et ajouter un nouveau script à l'arbre d'animation. Je vais l'enregistrer dans le dossier des scripts de personnages. Dans le nouveau script de l' arbre d'animation, notre objectif principal est de créer les trois mélanges d'animation que nous venons de mentionner. Dans la fonction de traitement, nous devrons définir le paramètre de quantité de mélange comme nous l'avons fait avec les espaces de mélange. Copier le chemin de propriété et spécifier une quantité de mélange. Faisons du blend amount une variable flottante privée avec une valeur par défaut de 1 %, et transmettons cette variable comme argument. Nous devrons ensuite modifier la valeur du montant du mélange fonction du fait que le personnage exécute ou non une action. Stockons l'état d'action lu par les machines dans une variable. Cette fois, en utilisant le mot clé self, puisque ce script est attaché à l'arborescence et en utilisant le chemin de propriété pour lire la machine à états d'action. Ensuite, dans la fonction de traitement, nous pouvons vérifier dans quel nœud se trouve actuellement la lecture de l'état d'action. Et s'il est à l'état inactif, cela signifie que le personnage n'effectue aucune action, et nous pouvons définir le montant du mélange à 1 %. Sinon, ils exécutent une action et nous pouvons la définir à 99 %. Mais il s'agira d'un changement instantané qui peut sembler un peu agité. Ainsi, au lieu de définir la variable directement sur 1 % ou 99 %, déplacons-la légèrement vers ce chiffre au fil du temps. En utilisant la fonction move towards, nous pouvons partir de ce qu'est actuellement la variable, en la déplaçant vers ce que nous voulons qu'elle soit par Delta. Cela fera prendre une seconde à la transition , ce qui est un peu long. Multiplions donc Delta par une nouvelle variable pour maintenir la vitesse de fusion, laquelle je donnerai une valeur par défaut de quatre. La transition prendra un quart de seconde. Pour activer ou désactiver les filtres, nous devons accéder directement au nœud Blend Two. Déclarer donc une variable pour la contenir, qui est de type animation node blend two. Nous pouvons y accéder à partir de la racine de l'arbre d'animation, en utilisant la fonction get node. Cette fonction accepte un nom de chaîne, que nous pouvons spécifier comme étant le même nom que celui que nous avons donné au nœud dans le graphe de l'arbre de fusion, inférieur plus haut. Veillez à ce que l' orthographe soit exactement la même. Nous ne sommes pas autorisés à activer ou désactiver les filtres pendant le traitement de l' arbre d'animation. Créons donc une fonction publique pour laisser le script du personnage le faire à notre place, indiquant à l'arbre d'animation si le personnage bouge ou non. Si le personnage bouge, les filtres doivent être activés pour intégrer les actions du haut du corps aux mouvements du bas du corps. Si le personnage est immobile, les filtres peuvent être désactivés pour n'utiliser que les animations d'action. Pendant que nous sommes ici, ajoutons également deux autres fonctions pour définir les quantités de mélange des espaces de mélange de locomotion afin qu'ils restent absents du script du personnage Définissez le paramètre verrouillé sur le mélange, acceptant un paramètre vectoriel à deux pour la quantité de mélange, en définissant le paramètre de quantité de mélange de l'espace de mélange verrouillé. Et définissez non verrouillé sur le mélange, acceptant un paramètre flottant pour la quantité de mélange, en définissant le paramètre de quantité de mélange de l'espace de mélange non verrouillé . De retour dans le script des personnages, nous pouvons constater que les chemins de propriété menant aux quantités de mélange ne sont plus valides, puisqu'ils ne font pas référence à la machine à états de mouvement. faisant abstraction de ces fonctions, nous conserverons les modifications apportées à l'arbre d' animation dans son propre script Dans le processus physique normal, nous devrons également indiquer à l'arbre d'animation si le personnage est en train de se déplacer ou non. Cependant, nous supposons maintenant que chaque personnage doit avoir ce script attaché à son arbre d'animation et qu'il utilise le même arbre d'animation. Nous allons donc enregistrer notre nouvel arbre d'animation en tant que ressource de projet. Je vais le mettre dans le dossier des scènes des personnages, avec la machine à états de mouvement des personnages. Mettez ensuite à jour chacun des autres personnages pour qu'ils utilisent le nouvel arbre d'animation et associez-y le script, afin qu'ils fonctionnent tous de la même manière. Je n'utilise que le barbare et les squelettes dans ce projet, mais le mage nocturne et le voleur devraient également être mis à jour si vous les utilisez Cela pose toutefois un nouveau problème. Si tous les personnages partagent la même ressource d'arbre de mélange, la modification de la propriété d'activation des filtres pour un personnage changera la même chose pour tous les personnages. Nous pouvons contourner ce problème en donnant à chaque personnage sa propre copie unique de l'arbre de mélange. Pour éviter d'avoir à reproduire chaque modification de l'arbre de mélange de chaque personnage à chaque fois, je vais utiliser un simple raccourci Dans le script de l'arbre d'animation, pendant la fonction Ready, je définirai la propriété racine de l'arbre de façon à ce qu'elle soit une copie de l'arbre de fusion. transmettez true comme argument, les sous-ressources utilisées par cette ressource seront également dupliquées . Depuis l'arbre de fusion, cet arbre d'animation utilise car sa racine n'est plus la même que celle qui lui avait été initialement attribuée. Nous devrons attribuer les valeurs de la lecture de l'état d'action et du nœud de fusion à deux après cette duplication. Désormais, chaque fois qu'un personnage est chargé, il crée sa propre copie unique de l'arbre de mélange et peut modifier son comportement de filtrage sans affecter les autres personnages. Revenons à la machine à états d'action des personnages. Notre personnage n'a pas encore d'objets équipés, alors transformons-le en idole désarmée Pour l'instant, conditionnons cette transition à la condition qu'ils ciblent un ennemi ou s'ils veulent attaquer en utilisant un court fondu croisé, et qu'ils puissent revenir en arrière s'ils ne visent pas un ennemi et ne veulent pas attaquer. Ensuite, pour garder les choses organisées. Ajoutez également une autre machine d'État nommée attaques non armées, et passez à la machine d'État si le personnage veut attaquer Ils peuvent ensuite redevenir une idole désarmée à la fin de l'animation d'attaque Modification de la machine à états désarmée. Commençons par le coup de poing masculin non armé A. Il passera à la fin ou au coup d'attaque masculin B non armé à la fin de l'animation, selon que le personnage souhaite ou non attaquer à nouveau Nous pouvons répéter ce schéma en passant à la fin animation ou à un coup de pied d'attaque masculin désarmé, selon que le personnage veut ou non attaquer à nouveau. Et nous pouvons créer une combinaison cycliste infinie en revenant au premier coup tant que le joueur continue d' appuyer sur le bouton d'attaque Lorsqu'ils arrêtent d'appuyer sur le bouton d'attaque, la machine à états passe à la fin, qui revient au mode inactif sans arme Il se peut également que nous souhaitions restreindre la façon dont le joueur se déplace lorsqu'il attaque. Par exemple, cela n'aurait aucun sens que le personnage bouge pendant l'animation du coup de pied, car ses pieds devraient être occupés. Je vais zoomer sur l'affichage de la piste d' animation pour mieux adapter la durée de ces animations. Ajoutons une fonction publique au script du personnage pour limiter les mouvements, acceptant un paramètre booléen si le personnage peut se déplacer ou non Nous allons ensuite définir la valeur opposée de la variable move. Dans l'animation Kick du personnage. Nous pouvons ajouter une piste de méthode d' appel appelant une méthode sur le nœud racine du personnage. Appelez la fonction de restriction des mouvements au début de l'animation, en utilisant true comme argument, en limitant les mouvements du personnage lorsqu'il donne des coups Et une autre touche à la fin de l'animation peut restaurer la capacité du personnage à se déplacer en remplaçant l' argument par faux. Mais pour que cela fonctionne, nous devons revenir à l'arbre de fusion et ajouter des fonctions aux filtres de fusion de deux nœuds afin que si le personnage se déplace et exécute une action, les fonctions d'action soient appelées. Essayons-le. Nos animations semblent fonctionner comme avant. Dès que nous demandons au personnage d'attaquer, il passe à l'état inactif sans arme avant de lancer une attaque Si nous continuons à donner des coups, ils continueront à attaquer à plusieurs reprises parcourant les différentes animations d'attaque à mains nues Il est même possible de se déplacer ou de sauter en attaquant, et le personnage utilisera animations appropriées pour le haut et le bas de son corps, mais il n'est pas autorisé à bouger ou à sauter lorsqu'il donne des coups Si nous nous accrochons à une cible, le personnage passe en état d'inactivité désarmé et bloque les transitions vers l'idole normale Notre personnage exécute maintenant des attaques à mains nues. Dans la leçon suivante, nous ajouterons des animations d'attaque par arme. Je te verrai dans la prochaine leçon. 6. Arme: Bonjour, mes amis. Dans la leçon précédente, nous avons combiné des actions du haut du corps avec des mouvements du bas du corps, permettant à notre personnage de lancer des attaques à mains nues Dans cette leçon, nous allons également ajouter diverses animations d'attaque par arme. Commençons par l'arbre d'animation des personnages où nous avons déjà des attaques désarmées, inactives et désarmées En suivant ce modèle, nous allons ajouter l'animation inactive à deux mains. Dans ce pack d'actifs, il n'y a pas d'animations inactives à une main ou à deux roues Mais nous pouvons simplement ajouter deux nouvelles copies de l'animation inactive et les renommer. À partir de chacune de ces animations inactives, nous pouvons ensuite nous connecter pour attaquer des machines à états qui fonctionnent exactement comme les attaques non armées Connexion de chacune des animations inactives aux attaques si le personnage veut attaquer, puis revenir à la fin de l'animation. Nous avons juste besoin d'un moyen de dire au personnage quel ensemble d' animations utiliser en fonction de son arme équipée. Dans ce projet, nous avons un script nommé enums, contenant toutes nos énumérations, auquel nous ajouterons un autre commençant par Unarmed par défaut, puis en listant chacun des types d'armes nécessitant des animations différentes, à savoir types d'armes nécessitant des animations différentes le mala à une main, le mala à deux mains et le mala à deux roues Il est important de savoir que l'énumération n'est qu'une liste numérotée, sorte que chacune de ces valeurs est en fait un nombre, commençant par zéro pour désarmé, en commençant par zéro pour désarmé, un pour une main pour un, deux mains pour deux mains pour deux et trois pour deux roues Dans le script du personnage, nous allons ajouter une autre variable nommée attack animation avec un type de notre nouvelle énumération Nous pouvons exporter cette variable à des fins de test. Changeons l'animation d'attaque du personnage pour qu'elle ne soit pas armée J'utiliserai la mêlée à deux mains. De retour dans la machine à états d'action, nous pouvons définir la condition de transition pour passer de l'état inactif au mode inactif sans arme, comme si l' animation d'attaque du personnage est nulle, ce qui est « non armé » dans notre énumération, et également au moins une des autres conditions en les mettant entre La condition de retour sera alors également l'inverse. Soit l' animation de l'attaque n'est pas nulle, soit les deux autres conditions sont remplies. En ajoutant des transitions à chacun des différents états d'inactivité, nous pouvons définir leurs conditions à ce qu'elles soient les mêmes que celles du mode inactif non armé, en utilisant uniquement une valeur différente pour l'animation d'attaque Je vais également donner à chacun d'eux le même temps de fondu croisé. Puis retour au mode veille dans des conditions logiquement opposées À l'intérieur de chacune des machines d'état d' attaque, nous pouvons utiliser les animations d'attaque de la même manière que nous l'avons fait pour les attaques non armées Il existe quatre attaques à une main différentes, crée un cycle d'animations différentes tant que le personnage veut continuer à attaquer. Répéter le même processus pour les attaques à deux mains, qui ne comportent que trois attaques différentes. Et la machine d' État à deux roues ne dispose également que de trois attaques Nous pouvons le tester dans le jeu, puisque l' animation d'attaque des personnages est réglée sur deux mains, ils utilisent les animations d' attaque à deux mains. Nous pouvons leur dire d'utiliser également des animations d'attaque à une main ou des animations à deux roues Il ne nous reste plus qu'à modifier la variable lorsque nous équipons le personnage d' objets Dans les ressources personnalisées, nous aurons besoin d'une classe plus spécifique pour décrire une arme héritée de l'équipement lui donnant le nom de classe weapon, nous pouvons ajouter une variable exportée supplémentaire pour stocker le type d'arme dont il s'agit, et nous pouvons utiliser la même énumération que le Ensuite, toutes les ressources du projet qui sont des armes peuvent être reclassées en armes, leur attribuant une valeur correspondant à leur type d'arme, afin que le personnage sache quelles animations utiliser pour l' équiper À des fins de démonstration, je vais mettre à jour le x pour en faire une arme à une main. N'oubliez pas de remplir à nouveau les champs qui ne sont pas reportés lorsque vous modifiez le script de ressource Le grade en tant qu'arme à deux mains et le poignard en tant qu'arme à deux roues Dans l'int ou dans le script que vous utilisez pour équiper des objets, nous aurons besoin d'une exception si l'objet à équiper est une arme. Et s'il s'agit d'une arme à deux mains ou d'une arme à deux mains, nous devrons retirer tout ce que le personnage possède dans son emplacement hors main Vérifiez d'abord si le fichier, la matrice d'équipements de progression contient quelque chose d'équipé dans l'emplacement secondaire. Je vais ensuite m'en servir pour indexer les boutons des objets dans l'inventaire du joueur et retirer le E correspondant à l'équipement du bouton. Ensuite, réglez également la valeur des ensembles d' équipements sur moins un ou sur vide. Je demanderai ensuite au personnage de mettre n'importe quel équipement dans sa prise de courant Dans le script du personnage, le personnage doit savoir ce qu'il tient entre ses mains. Ajoutons des variables de type nœud 3 D pour tenir leur équipement principal et secondaire. Notre personnage qui porte une arme peut alors également se voir ajouter une logique supplémentaire pour déterminer si l'objet est une arme L'objet principal du personnage peut ensuite être attribué à cette arme, et les animations d'attaque des personnages peuvent être définies pour correspondre à celles de l'arme équipée. Si l'objet est une arme à deux roues, j'ajouterai également une autre copie de l'arme dans la prise du personnage. Et assignez-le à la variable «   off hand ». Lorsque vous retirez une pièce d'équipement, si cet équipement est retiré de la main principale du personnage, nous pouvons définir la variable de la main principale sur zéro et vérifier également s'ils sont actuellement en double maniement si cet équipement est retiré de la main principale du personnage, nous pouvons définir la variable de la main principale zéro et vérifier également s'ils sont actuellement en double En cas de double maniement, je demanderai au personnage de saisir également l'objet de sa main Ensuite, je mettrai l' animation de l'attaque à désarmé. De même, si le socket à désactiver est le socket décalé, nous devons définir la variable offhand Nous n'avons plus besoin d'exporter l'animation de l'attaque, puisqu'elle sera désormais définie par l'arme équipée. Maintenant, le personnage commence à utiliser des attaques à mains nues. Mais lorsqu'on est équipé d' une arme à une main passe aux attaques à une main. Nous pouvons les équiper d'un bouclier, puis passer à une arme à deux mains, et le bouclier sera automatiquement retiré. Le personnage utilise désormais des animations d'attaque à deux mains. Passant aux dagues à deux roues, le personnage a un poignard dans les deux mains et utilise les animations d'attaque à deux roues. Après avoir équipé les dagues, le personnage recommence à utiliser des attaques à mains nues La dernière chose dont nos attaques ont besoin, ce sont des boîtes à hanches. Zones de collision pour détecter si l'attaque touche réellement un ennemi et lui inflige des dégâts. En ouvrant les scènes d'armes, nous pouvons ajouter des boîtes de frappe à chacune d'elles. Utiliser un nœud de zone 3D, qui ne sera pas surveillé ou surveillable par défaut, couche de collision ni aucun masque de collision tant qu'on ne leur aura pas demandé de le faire Comme ces modèles de personnages ont des membres courts et des armes légères, leurs attaques ne vont pas très loin. Je vais donc être très généreux avec leurs boîtes à hanches, en les rendant plus grandes que les armes réelles. Création d'un nouveau script pour les armes, en héritant de l'objet Je vais remplacer le script attaché au nœud racine des armes et l'ouvrir pour le modifier. Nous pouvons indiquer à l' arme de saisir ou référence à sa zone de frappe en utilisant Add on Ready. Ajoutez ensuite des fonctions pour définir un nouvel entier pour le masque de collision des cases à cocher. Et une autre qui activera ou désactivera la hitbox en définissant sa propriété de surveillance Le personnage qui détient cette arme peut désormais spécifier dans quelle couche de collision trouvent ses ennemis et activer la case de frappe lorsqu'il fait pivoter l'arme Le modèle de personnage aura également besoin d' une boîte à hanches pour les attaques à mains nues Tout comme les armes, elles n' ont pas besoin d'être surveillées, surveillables, ni de couche de collision ni de masque de collision et elles auront une forme de collision surdimensionnée Mais nous n'avons pas besoin de le positionner pour le moment et nous pouvons déléguer cette responsabilité aux animations. Dans le script du personnage, nous pouvons saisir une référence à la boîte à hanches désarmée en utilisant Add-on Ready N'oubliez pas d'ajouter une case à chaque caractère ou d'utiliser la fonction get node ou null pour éviter les erreurs. Exportons également une couche physique en trois D pour contenir la couche de collision des ennemis de ce personnage. Cela ajoutera une grille de chiffres dans l' inspecteur, tout comme les couches de collision dans la zone des trois propriétés des notes en D. De cette façon, nous pouvons spécifier que ce personnage essaiera de toucher des objets sur la couche de collision Blessure ennemie, que j'ai qualifiée de couche 18. Pendant ce temps, les ennemis utilisant le même script peuvent définir leur couche de collision ennemie comme couche de collision HRT du joueur Pendant la fonction de préparation, nous pouvons configurer le masque de collision de la boîte à hanches désarmée pour qu'il devienne la couche de collision de l'ennemi De même, chaque fois qu'une arme est équipée, nous pouvons configurer son masque de collision pour qu'il soit la couche de collision de l'ennemi, afin qu'il sache quelles couches masquer, peu importe qui la détient. Nous aurons ensuite besoin de certaines fonctions script du personnage pour activer et désactiver les boîtes à hanches des armes pendant les animations d' attaque, acceptant un paramètre booléen spécifiant si la boîte à hanches est spécifiant si la boîte à hanches est activée ou désactivée et un entier Et je vais lui donner une valeur par défaut de un pour désigner la main principale. À l'aide d'une déclaration de match, nous pouvons créer trois cas distincts, activant la boîte à hanches pour les attaques à mains nues, les attaques à main principale ou les attaques hors main Si vous n'êtes pas armé, nous pouvons activer la propriété de surveillance de la hanche non armée Qu'il s'agisse d'une main principale ou d'une main désactivée, nous pouvons demander à l'arme d' activer ou de désactiver sa zone de frappe Les animations de nos personnages peuvent ensuite être ajoutées à des pistes pour activer et désactiver les boîtes à succès Je vais juste vous montrer avec une attaque de chaque type, commençant par un coup d'attaque masculin à une main. En ajoutant une piste de méthode d'appel à cette animation, nous nous attendons généralement à ce que la zone de frappe soit activée juste après qu' elle commence à osciller. En ajoutant une touche à ce moment, nous pouvons changer l' argument booléen en vrai pour activer la case de frappe de l'arme principale du personnage. Puis désactivé à la fin du swing en remplaçant l'argument par false Cela empêchera les ennemis d'entrer dans l'arme lorsqu'elle ne bouge pas et d'être blessés par celle-ci, et n'infligera des dégâts que lorsque le personnage manipule réellement l'arme avec force Le processus est le même lorsque vous maniez une arme entre les mains. L'ajout d'une piste, puis fonction de cadrage des touches appelle à activer la case de frappe au début du swing de l'arme et désactiver à la fin du En cas de double maniement, nous devrons spécifier quelle boîte à hanches est activée, qu'il s'agisse de la main principale ou de la main libre, en modifiant également le paramètre entier à deux, si la boîte à hanches activée ou désactivée appartient à l'arme à main levée Et une fois désarmés, nous devrons non seulement activer la boîte à hanches, mais également la positionner au bon endroit Utiliser une piste de propriétés pour encadrer la propriété de position des hip boxes. Nous allons ensuite changer l' argument entier dans les appels de fonction à zéro pour indiquer que nous voulons utiliser la boîte à hanches non armée Il est conseillé de s'assurer que la boîte à hanches est en place au moins un cadre avant de l'activer. Il est utile d'utiliser des vues orthogonales pour positionner la hanche exactement sur le poing du personnage sous au moins deux angles différents Cliquez ensuite sur l'icône en forme de clé pour cadrer cette position dans l'animation. Nous ne serons pas en mesure de tester ces boîtes à hanches avant la prochaine leçon, lorsque nous ajouterons des boîtes de blessure à toucher. La boîte à hanches s' activera non seulement avec l'animation, mais suivra également le poing du personnage. N'oubliez pas que vous devez effectuer ce processus pour chaque animation d' attaque. Notre personnage attaque désormais avec des animations différentes pour chaque type d'arme. Dans la leçon suivante, nous autoriserons personnages à se blesser et à subir des dégâts. Je te verrai dans la prochaine leçon. 7. Hit: Bonjour, mes amis. Dans la leçon précédente, nous avons ajouté des boîtes de frappe à nos armes et à nos animations d'attaque. Dans cette leçon, nous allons ajouter des boîtes de blessures à nos personnages afin qu'ils puissent être touchés par des attaques. La boîte Hurt d'un personnage n'est qu' un autre nœud de la zone 3 D. Nous allons ajouter des modèles de personnages. Ils ne seront pas surveillés, mais pourront être surveillés par les boîtes à succès Ils existeront soit sur la couche Hurt Box du joueur , soit sur la couche Heart Box de l'ennemi de manière appropriée. Mais il n'est pas nécessaire de masquer quoi que ce soit puisqu'ils ne surveillent pas de toute façon. Pour la forme de collision des boîtes Hert, une autre capsule est très courante, mais elle est généralement plus petite que la forme de collision du corps du personnage et entièrement contenue dans le modèle du personnage Ce ne serait pas juste pour le joueur de se faire toucher par quelque chose qui ne semble pas entrer en contact. N'oubliez pas que les armes utilisent des boîtes à hanches surdimensionnées Il serait donc raisonnable de sous-dimensionner les boîtes à cœur , mais je vais adapter la mienne à la tête et au corps du personnage Je vais ensuite copier-coller la même boîte en cœur dans les scènes de mes personnages ennemis, remplaçant leur couche de collision par la couche HRT ennemie Ensuite, dans nos scènes d'armes, je vais utiliser la hache comme exemple. Nous devrons connecter le signal saisi par la zone de frappe au script de l'arme. Si cette arme entre dans la boîte à blessures d'un personnage, nous aurons besoin de cette arme pour infliger des dégâts à ce personnage Pour l'instant, ajoutons une variable publique pour ces dégâts infligés par les armes. Lorsque la collision se produit, nous aurons besoin d'une référence au personnage auquel appartient la case Hurt. Dans mon projet, ce sera toujours le nœud parent de la boîte Hurt. Nous pouvons ensuite demander au personnage de subir des dégâts, en utilisant les dégâts de l'arme comme argument. Il peut également être intéressant de connaître la direction d'où proviennent les dégâts. Nous pouvons donc utiliser la différence entre leurs positions globales normalisée. Pour conserver toutes nos informations sur les armes au même endroit, leurs dégâts doivent être ajoutés au fichier de ressources en tant que variable exportée, et je vais leur donner une valeur par défaut de deux dégâts. Chaque fichier de ressources d'arme peut ensuite spécifier l'ampleur des dégâts infligés par cette arme N'oubliez pas de connecter également le signal de zone saisie pour chaque scène d' arme. De même, la boîte à hanches désarmée de notre personnage a également besoin d'une connexion de signal pour indiquer au personnage d' infliger des dégâts à un joueur non armé Prendre le parent de la Hurt Box, lui dire de subir un dommage et lui donner la direction normalisée Ensuite, dans le script du personnage, lorsque nous créons l'instance d'arme, nous pouvons définir le même nombre de dégâts que celui de la ressource. I. Pendant que nous sommes ici, écrivons également la fonction de prise de dégâts dans la zone de combat. Accepter le montant des dégâts à encaisser, ainsi que la direction d'où ils proviennent, lui attribuant la valeur par défaut du vecteur 30. Pour subir des dégâts, nos personnages auront besoin de santé. Je vais ajouter une catégorie d'exportation pour les variables de combat. Déclarez ensuite un pour la santé maximale des caractères sous la forme d'un entier , que je mettrai à cinq. Et leur état de santé actuel est également un entier, que nous pouvons définir à leur santé maximale en utilisant Add-on Ready. Déclarons également quelques paramètres booléens indiquant si le personnage est mort ou non et si les dégâts subis ont été infligés par derrière, et saisissons également une référence à la boîte à rats du personnage en utilisant Add on En cas de dégâts, la santé actuelle du personnage sera réduite en fonction du montant des dégâts subis, mais nous ne voulons pas qu'elle passe en dessous de zéro. Nous pouvons donc utiliser la fonction max pour le régler sur ce calcul ou sur zéro, selon la valeur la plus élevée. Le booléen vu de derrière peut alors être défini sur true si le produit scalaire de la direction des dégâts par le vecteur de base avant du personnage est un Si la santé actuelle du personnage après avoir subi des dégâts est nulle, il mourra. Dans le cas contraire, ils seront touchés. Bien que l'animation de la mort soit automatique, l'animation des victimes peut être gérée par le script Animation Trees, et nous lui indiquerons si les dégâts subis étaient inférieurs ou supérieurs à un certain seuil. De cette façon, nous pouvons modifier l'animation du coup en fonction de l' ampleur des dégâts subis. Nous pouvons également vouloir suivre l' état de santé d'un personnage ou le moment de sa mort. Ce serait une bonne idée de diffuser ces deux événements sous forme de signaux. déclarant un signal chaque fois que la santé du personnage change, nous pouvons utiliser un pourcentage de santé restante comme argument et un autre signal pour indiquer le moment où le personnage meurt. Émettez ensuite le signal de changement de santé s'ils subissent des dégâts et le signal de mise à mort si le personnage meurt. Pour calculer leur pourcentage de santé restante, il suffit de diviser leur santé actuelle par leur santé MX. Mais comme ces deux valeurs sont des entiers, le résultat sera également un entier, sorte qu'il n'en résultera que zéro ou un Nous devrons d'abord lancer au moins l'un d'entre eux à flot avant de procéder à la division, afin que le résultat soit également Si nous ne voulons plus que les personnages morts soient affectés par les collisions, nous pouvons également définir leur couche de collision à zéro, leur masque de collision à un, afin qu'ils ne soient affectés que par le terrain et définir leur propriété surveillable H rtbach Il est également possible qu'un personnage soit touché ou tué pendant qu'il exécute une action. Nous devons donc également garder une trace des actions interrompues susceptibles de provoquer des problèmes et les corriger dans le cadre d'une fonction privée. Par exemple, nous devrions probablement désactiver toutes boîtes à hanches si leurs attaques étaient interrompues, ce que nous pouvons également faire dans une fonction séparée, vérifiant si des références à chacune d' entre elles existent avant de les désactiver. Dans l'arbre d'animation des personnages, nous voulons que le personnage soit tué ou touché interrompe et annule toutes les autres animations Comme cet arbre de fusion est déjà enregistré en tant que ressource, nous pouvons le supprimer de l'arbre d'animation et le remplacer par une machine à états. À la base de la machine à états, nous allons commencer par les animations de mort de nos personnages, car celles-ci auront la priorité absolue par rapport à toutes les autres animations. Ajoutez ensuite une autre machine à états pour les animations à succès. Nous passerons de l'attaque A à la mort si le personnage est mort. Avec un court fondu croisé. Ou bien la mort B s'ils ont également été touchés par derrière en lui donnant cette priorité en la mettant à zéro. n'a peut-être pas besoin Notre personnage n'a peut-être pas besoin de revenir de sa mort, mais cela ne fait pas de mal d'ajouter cette transition à condition qu'il ne soit pas mort. Dans la machine à états des hits, nous allons faire la même chose avec les animations des hits et ajouter notre arbre de fusion comme animation par défaut ici. Activer les transitions vers les animations sélectionnées et revenir à l'arbre de fusion à la fin de leurs animations. Avec un fondu croisé à la fois dans et hors des animations visitées, la machine d' état de l'arbre d'animation mise à jour, nous l'enregistrerons en tant que ressource du projet. Je vais appeler ça des animations de personnages. Et pour la dernière fois, chaque personnage peut être mis à jour pour utiliser la nouvelle machine à états. Dans le script Animation trees, nous aurons besoin d'une référence à la lecture de l'état du hit. De plus, comme nous avons mis à jour le format de l'arbre, nous devrons mettre à jour tous ces chemins de propriétés. Nous allons maintenant accéder au nœud de fusion en obtenant le nœud sélectionné, puis le nœud d'arbre de fusion, et enfin, le nœud de mélange inférieur et supérieur. donnant une définition à la fonction get hit, nous pouvons recevoir le paramètre booléen comme si le caractère est légèrement touché ou non Dites ensuite à l'état touché de passer à A s'il a été touché légèrement ou B s'il a été touché plus fort. Essayons-le. Si nous frappons le squelette, il réagit lorsqu'il est légèrement touché, en utilisant une hache et en l' attaquant à nouveau. Ils sont plus durement touchés. Un troisième coup et ils meurent en tombant en arrière puisqu'ils ont été touchés par l'avant Nous pouvons équiper la grande hache, que j'ai définie pour infliger cinq dégâts, tuer un autre squelette par derrière, et ils tombent en avant en mourant. Ce serait également bien de pouvoir suivre l'état de santé du personnage du joueur sur l'interface utilisateur. Ajoutons un nœud de contrôle et appelons-le jauge de santé. Je vais le mettre derrière tout le reste de l'interface utilisateur. Cela nécessitera un texte direct pour dessiner la bordure, un montage de couleur en guise de remplissage et un autre texte direct si nous voulons une icône Je vais utiliser un cadre coulissant fin comme image de bordure. Il est très grand, je vais donc le réduire au quart de sa taille. Et je vais utiliser une icône, un petit cœur plein pour l'icône. Redimensionnez-le et positionnez-le là où il est beau par rapport à la bordure Je vais ensuite définir la couleur de la couleur, etc., pour qu'elle corresponde à la couleur du cœur, et définir sa position et ses dimensions pour remplir la jauge. Je vais réinitialiser sa propriété de taille, ancrer dans le coin inférieur gauche. En cliquant et en faisant glisser le pointeur sur la propriété size x du remplissage, nous pouvons voir comment la jauge peut facilement être réglée sur n'importe quel pourcentage En joignant un script à la jauge de santé, nous pouvons simplement l'appeler jauge pour réutiliser pour toute autre jauge que nous souhaiterions Nous allons récupérer une référence à la couleur de remplissage ret en utilisant add on ready, et également déclarer une variable contenant le point de taille x du remplissage lorsque la jauge est complètement remplie, quoi la propriété size point x à quoi la propriété size point x est définie lors du premier chargement. Écrivez ensuite une fonction publique nommée set value, acceptant un paramètre de pourcentage à virgule flottante. Il suffit de définir la propriété size x de la couleur t comme étant le pourcentage multiplié par la taille maximale. En connectant le signal de changement de santé du personnage du joueur à la fonction de réglage de la valeur des jauges, il suivra désormais automatiquement l'état de santé du joueur Pour tester la jauge de santé. Je vais juste dire au personnage de subir deux dégâts à chaque fois que le joueur appuie sur le bouton Exécuter. Nous pouvons maintenant voir que la jauge de santé du personnage s'épuise et que le personnage meurt lorsqu'elle est vide. Je vais ensuite remettre à zéro la ligne de prise de dégâts pour qu'elle fonctionne. Notre personnage est maintenant touché et subit des dégâts à cause des attaques. Et dans la prochaine leçon, nous allons permettre aux personnages d'éviter de se faire toucher en esquivant Je te verrai dans la prochaine leçon. 8. Dodge: Bonjour, mes amis. Dans la leçon précédente, nous avons autorisé nos personnages à être attaqués, subir des dégâts et à mourir. Dans cette leçon, nous allons les aider à éviter les dégâts en esquivant. Commençons par les paramètres du projet, dans l'onglet Carte d'entrée, en ajoutant un événement d'entrée pour l'esquive J'utiliserai la barre d'espace ou le bouton droit de ma manette. Dans le script du joueur, nous pouvons utiliser les mêmes méthodes que le saut et l'attaque pour amortir l'esquive. Dans le script du personnage, nous aurons besoin d'une variable indiquant si le personnage veut esquiver ou non. Mais une esquive n'est pas une simple saisie. Il nécessite également une direction sous forme de vecteur trois. Dans la zone de combat, nous aurons besoin d'une fonction d'esquive et d'une fonction d'annulation de l'esquive, en définissant la variable booléenne Et avec toute entrée mise en mémoire tampon, toutes les autres entrées mises en mémoire tampon seront définies sur false Comme nous enregistrons déjà la direction d'entrée dans le script du personnage, nous pouvons vérifier s'il s'agit du vecteur 30 au moment où le personnage a reçu l'ordre d'esquiver. Si je ne donne aucune information, je veux que le personnage esquive en arrière. Je vais utiliser le vecteur avant de Character Rigs Bases, multipliant par moins un pour l'inverser Si nous donnons une orientation, je veux que le personnage esquive dans cette direction, mais toujours avec force. Je vais normaliser la direction pour supprimer la magnitude de l'équation. Dans la machine à états de l' arbre d'animation des personnages, naviguez entre les animations de la mort et des touches dans l'arbre de mélange, et enfin, dans la machine à états de mouvement Nous pouvons ajouter les animations d'esquive dans un espace de fusion bidimensionnel. Passage de la locomotion à l' esquive si le personnage veut esquiver, puis retour à la locomotion à la fin de l'animation Les deux avec un fondu croisé. Comme cela est lié à la locomotion, l'esquive ne sera exécutée que lorsque le personnage est au sol Vous pouvez également associer des esquives aériennes à état d'inactivité du saut Dans l'espace du Dodge Blend, je vais remplacer le clivage de la grille par un facteur d'un Ajoutez ensuite les animations Dodge forward, Dodge back, Dodge left et esquive right qui seront mélangées pour que le personnage puisse esquiver dans n'importe quelle direction Le script de l'arbre d'animation devra être capable de définir la quantité de fusion de cet espace de fusion sous forme de vecteur deux, la même manière que nous avons défini la quantité de fusion des animations bloquées lors du mitraillage Dans le script du personnage, lorsque vous demandez au personnage d'esquiver, nous pouvons demander à l'animation de définir cette quantité de mélange. Mais la direction de l'esquive est un vecteur trois dans l'espace global, tandis que le montant du mélange pour l'esquive est un vecteur deux dans l'espace local des plates-formes de personnages Nous pouvons calculer la quantité de mélange en comparant la direction d'esquive aux vecteurs des espaces de montage à l'aide d'un produit ponctuel. Je vais devoir inverser le montant du mélange x multipliant par moins un Si nous essayons cela, l'animation d'esquive se joue trois fois et le personnage ne bouge pas vraiment. L'animation se répète car Wants to esquive est vrai pendant une seconde complète, mais l'animation ne dure que 0,4 seconde. Il se répétera donc autant de fois que possible jusqu'à ce que la variable wants to esquive soit redéfinie false avant la fin de la seconde. Nous devrons définir la variable false une fois que l'esquive aura été exécutée avec succès et appliquer de la vélocité pour déplacer le personnage. En ajoutant une autre fonction, un peu comme l'application de la vélocité de saut, nous appliquerons la vélocité d'esquive et appellerons cette fonction depuis l'animation. Si cette fonction est appelée, le personnage a réussi à esquiver et nous pouvons définir la variable sur false pour éviter que d'autres esquives ne se produisent à partir d'une seule entrée Ensuite, nous définirons la vélocité du personnage comme étant la direction d' esquive multipliée par la force d'esquive. Cela créera une impulsion soudaine de vélocité, déplaçant rapidement le personnage dans la direction dans laquelle il esquive Création d'une autre variable exportée pour la force d'esquive du personnage. Je vais le mettre à huit. Vous voudrez peut-être aussi que notre esquive ait des montures pour les yeux, abréviation de lunettes d'invincibilité Il s'agit d'une durée pendant laquelle le personnage ne peut pas être blessé par des attaques Tout comme nous avons une fonction appelée par nos animations d'attaque pour activer ou désactiver la case Hip, nous aurons également une fonction appelée par les animations d'esquive pour activer et désactiver la case Hurt. Nous devons utiliser set deferred pour définir la propriété monitorable de la case Hurt sur la valeur active au cas où cela se produirait lors d'une collision Comme il est possible que nous souhaitions appeler cette fonction à la suite d' une collision, nous ne pouvons pas activer ou désactiver les collideurs pendant leur traitement Dans les animations des personnages, nous devrons ajouter des pistes d'appels de fonctions à chacune des animations d' esquive de nos personnages. Je vais d'abord désactiver la case Hurt du personnage. Ensuite, lorsque le personnage aura l'air commencer à se déplacer dans l'animation, j'appliquerai la vélocité d'esquive. Une fois qu'ils auront eu le temps d'utiliser la vélocité d'esquive pour utiliser la vélocité d'esquive pour empêcher le personnage de passer à l'attaque, empêcher le personnage de passer à l'attaque, je réactiverai la case HRT en remplaçant l' argument par vrai Répétez ensuite le même ensemble d' appels de fonction pour chacune des animations d' esquive. Bien que cela ne devrait pas se produire avec ce code tel qu'il est actuellement, il est possible que le personnage soit interrompu pendant qu'il esquive, ce qui signifie que la case à cocher ne sera peut-être jamais réactivée Selon le fonctionnement du jeu, vous pouvez inclure l'activation de la case du personnage dans les actions d'interruption. Maintenant que la vélocité d'esquive est appliquée, je n'aime pas vraiment la façon dont l'animation d'esquive déplace réellement la position racine du personnage, ce qui entraîne des mouvements brusques, fois avant et en sortant de l' En ouvrant les animations, je vais donc supprimer les images clés racines animations d'esquive. Garder le personnage ancré là où le personnage doit être, conformément à la physique du corps du personnage. Ensuite, je vais également répéter cela pour les autres animations d'esquive. cours de jeu, nous pouvons voir l'arbre des scènes distantes, trouver la boîte à rats du personnage et faire attention à la propriété surveillable esquive définit la propriété surveillable sur false, puis la redéfinit sur true, et le personnage anime l'esquive de manière plus fluide avec la vélocité grâce à la suppression des images-clés et le personnage anime l'esquive de manière plus fluide avec la vélocité grâce à la suppression Maintenant que l'esquive s'anime et fonctionne correctement, voyons maintenant si nous voulons permettre au personnage d'attaquer et d' esquiver en même temps De plus, le personnage devrait-il être autorisé à attaquer ou à esquiver s'il est touché ? Si nous ne voulons pas autoriser ce comportement, nous devrons savoir quand le personnage attaque, esquive ou est touché Ajoutons quelques variables booléennes supplémentaires à notre script de personnage : attaque, esquive et est Tous ces éléments devront être exportés pour être accessibles au nœud du lecteur d'animation. À l'aide des pistes de propriétés, les animations touchées peuvent définir la variable is hit sur true au début de l'animation. Et revenons au faux à la fin. Ensuite, dans l'arbre d'animation, lors de la transition de la locomotion à l'esquive, nous pouvons vérifier que le personnage veut esquiver et que rien n'est touché et que rien n'attaque et que rien Avant de passer à un état d'attaque, nous pouvons vérifier non seulement si le personnage veut attaquer, mais aussi s'il n'est pas touché et s'il n'esquive pas Nous pouvons ensuite répéter le processus de définition des variables booléennes dans les animations d'esquive Chacun définit la variable is dodging sur true au début et false à la fin Encore une fois, pour chaque animation d' attaque, définissez la variable « attaque » sur true au début des animations d'attaque et sur « baisse » à la fin. Si les attaques ou les esquives sont interrompues, nous devons également remettre ces variables sur false Il est également possible que le personnage meure en interrompant l'animation à succès Nous allons donc définir la variable is hit sur false ici. Pour que la variable d'attaque soit définie par la machine à états d'action, nous devons également activer le filtre correspondant ainsi que la position de la case de frappe. Afin de vérifier si l' esquive fonctionne réellement, nous aurons besoin que les ennemis commencent à attaquer. Si vous n'avez pas encore configuré les animations d'attaque ennemie, un moyen simple de le faire est de copier le lecteur d'animation des personnages et de le coller dans la scène ennemie. Nous pouvons ensuite indiquer à l'arbre d'animation d'utiliser le nouveau lecteur d'animation. Et tant que l'ennemi a la même structure osseuse que le personnage, les animations fonctionneront toutes de la même manière. Sinon, vous devrez configurer l'ennemi pour qu'il dispose d' au moins une attaque capable d'activer une boîte à hanches, masquant ainsi la boîte en T du personnage Pour lancer l'attaque de l'ennemi, je vais simplement lui attacher un nœud vide dans la scène de niveau. Avec un simple script, leur disant d'attaquer. Je vais créer un nouveau dossier pour les scripts ennemis et l'appeler attaque. Après avoir saisi une référence au personnage en tant que parent de ce nœud, je vais lui demander d' attaquer dans la fonction Ready Comme la variable ne sera jamais remise à false, c'est tout ce qu'il faut pour que les ennemis exécutent des attaques à l'infini Essayons de lancer le jeu avec des formes de collision visibles. Et visualisez l'arbre des scènes distantes où nous pouvons voir les valeurs de toutes nos nouvelles variables. Le personnage attendra la fin d'une attaque avant d' effectuer une esquive et vice versa. Si nous laissons le squelette toucher le personnage, celui-ci subit des dégâts et ne pourra ni attaquer ni esquiver tant que l'animation du personnage ne sera pas terminée. Et nous pouvons esquiver l'attaque du squelette grâce à notre nouvelle action d'esquive Notre personnage esquive désormais pour échapper aux attaques et limite les moments où le personnage peut effectuer certaines actions Dans la leçon suivante, nous autoriserons personnages à bloquer les attaques entrantes à l'aide d'un bouclier. Je te verrai dans la prochaine leçon. 9. Bloc: Bonjour, mes amis. Dans la leçon précédente, nous avons aidé nos personnages à éviter subir des dégâts en évitant les attaques Dans cette leçon, nous allons leur permettre de bloquer les attaques à l' aide d'un bouclier. Commençons par les paramètres du projet, dans l'onglet Carte d'entrée, et ajoutons un événement d'entrée à bloquer. J'utiliserai le bouton droit de la souris et le bouton gauche de l'épaule de ma manette. Dans le script du joueur, le bouton de blocage n'a pas besoin d'être mis en mémoire tampon, car il se comporte davantage comme le bouton d'exécution, modifiant ainsi le comportement du personnage lorsque le bouton est maintenu Envoi d'un signal au personnage pour qu'il bloque ou non, selon que le bouton est enfoncé ou relâché. Le script de caractères peut ensuite stocker cette valeur dans une variable. Il veut bloquer. Mais contrairement aux autres variables, il n'est pas vraiment nécessaire de mettre en mémoire tampon l'entrée bloquante. Ajoutez ensuite une fonction dans la section de combat qui définit cette variable. Dans l' arbre d'animation des personnages, la machine à états navigue vers la machine à états d'action Nous pouvons ajouter l' animation du bloc et y faire la transition si le personnage souhaite bloquer avec un court fondu croisé. Revenez ensuite à s' ils ne veulent pas bloquer. obtenant une vue du personnage et en se mélangeant dans l'état d'action, cette animation amène le personnage à lever son bouclier Une fois cette animation terminée, nous pouvons passer à l'animation de blocage, qui doit être réglée en boucle pour maintenir le bouclier en place tant que le joueur maintient le bouton de blocage enfoncé. Cela redeviendra également inactif si le personnage ne veut plus bloquer avec un court fondu croisé. Nous souhaiterons peut-être également pouvoir passer à l'animation par blocs à partir de certains de nos autres états inactifs, tels que les états non armé et inactif d' une seule main Pour réduire le nombre de transitions, je vais d'abord combiner les états d'inactivité et d'inactivité unilatérale en combinant logiquement les conditions de transition pour atteindre l'état d'attaque unilatérale Si l'animation d'attaque en est une, ils veulent attaquer, ils ne sont pas touchés et ils n'esquivent pas Revenez ensuite au mode inactif à la fin de l'animation d'attaque. supprimant l'état d'inactivité d'une main, je vais ensuite réorganiser les autres états pour qu'ils soient un peu plus organisés Désormais, une idole inactive ou désarmée peut passer au bloc, si le personnage veut bloquer, et revenir directement à une idole désarmée, si l' animation d'attaque du personnage est nulle et qu'il a une cible ou veut attaquer, mais qu'il ne veut pas bloquer Avec une priorité de zéro. Désormais, un joueur inactif ou non armé peut passer au mode bloc si le personnage le souhaite. Les états de blocage et de blocage peuvent ignorer l'état d'inactivité et revenir directement au mode inactif non armé avec une priorité de zéro De cette façon, le personnage n'a pas à passer par deux états d'inactivité différents entre le blocage et l'attaque. Si nous l'essayons, notre personnage peut passer à l'animation du bloc appuyant sur le bouton de blocage et revenir au mode veille lorsque le bouton de blocage est relâché. Mais il serait plus logique de restreindre le personnage à n'utiliser cette animation s'il est équipé d'un bouclier. Pour ce faire, nous aurons besoin d'un autre script de ressources. Hériter de l'équipement, en lui donnant le nom de classe shield Si vous souhaitez que vos boucliers aient des variables différentes, nous pouvons les définir ici. Ajoutons une variable pour le montant des dégâts réduits en bloquant avec ce bouclier avec une valeur par défaut de un. Accès à la ressource personnalisée Barbarian Round Shields. Nous pouvons le transformer en bouclier et modifier le montant de la réduction des dégâts si nous le voulons. N'oubliez pas de renseigner à nouveau toutes les propriétés réinitialisées à la suite de ce changement de classe et de mettre à jour tous les boucliers pour utiliser le nouveau script de classe Dans la scène du bouclier, nous devrons être en mesure de stocker les variables issues de la ressource objet dans le bouclier comme nous l'avons fait avec l'arme. En ajoutant un nouveau script, il contiendra simplement une variable entière de réduction des dégâts et une fonction fictive d'activation de la boîte à hanche, qui ignorera l' argument booléen et La raison pour laquelle cela est nécessaire deviendra claire dans une minute. Nous pouvons ensuite remplacer le script attaché à notre bouclier par le nouveau. Dans le script du personnage, ajoutons une autre variable à la catégorie d'équipement pour savoir si le personnage possède ou non un bouclier. Lorsque vous enfilez une pièce d'équipement, s'il s'agit d'un bouclier, nous le configurons comme un équipement original, nous transmettons la valeur de réduction des dégâts de la ressource de l'objet au bouclier, et le bouclier de l'ensemble est équipé pour fonctionner. Comme la variable « off hand » consiste désormais à tenir un bouclier au lieu d'une arme, si vous interrompez les actions du personnage toutes les boîtes à hanches seront désactivées Et comme le off hand n'est pas nul, nous lui demandons de désactiver sa boîte à hanches. Mais nous avons demandé au bouclier d'ignorer cette demande. Ensuite, lorsque vous retirez une pièce d'équipement, si la prise est désactivée, nous pouvons supposer que le personnage ne tient plus Ensuite, lorsque vous demandez au personnage de bloquer, nous pouvons ajouter la condition selon laquelle le personnage doit également être équipé d'un bouclier. Le script d'inventaire nécessitera également quelques conditions supplémentaires lors de l' équipement d'un bouclier afin d'empêcher le personnage de s'équiper d'un bouclier alors qu' afin d'empêcher le personnage de s'équiper d'un bouclier alors est déjà occupé par une arme à deux mains ou à deux mains Ce processus varie en fonction du fonctionnement de votre inventaire et de vos systèmes d' équipement. Si l' objet sélectionné est un bouclier, le personnage a quelque chose d'équipé dans sa main principale, et que le personnage utilise actuellement les animations à deux mains ou à deux roues, alors je déséquiperai la prise principale et je demanderai au personnage de porter l'équipement dans sa main demanderai au personnage de porter principale Si on l'essaie. Le bouton de blocage est désormais ignoré si le personnage ne possède pas d'équipement de bouclier. Nous pouvons équiper une arme à deux mains, puis équiper le bouclier. L'arme à deux mains est automatiquement déséquipée, puis le bouclier est équipé Et maintenant, le personnage peut bloquer avec le bouclier. Voyons ensuite comment entrée de blocage fonctionne avec nos autres actions. Si le joueur bloque et décide d' attaquer ou d'esquiver, je voudrais que ces actions soient prioritaires pour interrompre le blocage. Mais si nous définissons simplement la variable wants to block sur false, le joueur devra relâcher le bouton de blocage et appuyer à nouveau dessus pour continuer à bloquer. Au lieu de cela, nous pouvons déclarer une autre variable booléenne. Appelons cela un bloc d'interruption. Si le personnage veut attaquer ou esquiver, cette variable peut être définie sur true. Et lorsque l'attaque ou l'esquive est terminée, nous pouvons la remettre sur false pour permettre au personnage de continuer à bloquer automatiquement. Je vais simplifier la fonction d'ajout de vélocité d' esquive pour simplement appeler Annuler l'esquive. Ensuite, dans l'arbre d'animation, nous pouvons ajouter les conditions de transition hors bloc ou de blocage à inclure si le bloc est interrompu. Et ne laissez pas les transitions revenir au bloc tant que le blocage n'est plus interrompu. Désormais, le personnage arrête de bloquer pendant l'attaque et revient automatiquement au blocage tant que le bouton de blocage est toujours enfoncé. Et il en va de même pour l'esquive. La dernière chose à faire est de réduire les dégâts causés par les attaques entrantes lors du blocage. Pour cela, nous devons savoir si le personnage bloque. Comme le blocage n'est pas limité à une seule animation et aux boucles d'animation, nous ne pouvons pas simplement demander à l' animateur de définir une variable booléenne sur true ou false Ajoutons l'animation Block Hit. Activation de la transition entre le blocage et le retour à cette animation à la fin de l'animation. Ce que nous contractons pour savoir si le personnage bloque, c'est dans quel état se trouve actuellement cette machine à états. S'il est bloqué ou bloqué, le bouclier du personnage est levé. L'animation du bloc est également assez longue. Cela inclut non seulement le soulèvement du bouclier, mais également un cycle de blocage de l'animation. Je ne pense pas que le personnage doive être considéré comme bloquant tant que le bouclier n'est pas complètement levé, mais je ne veux pas non plus attendre la fin de l'animation du bloc. Dans le lecteur d'animation du personnage, je vais donc réduire la durée de l'animation du bloc pour qu'elle s'arrête une fois que le bouclier est levé au tiers de seconde. Dans le script des arbres d'animation, ajoutons une fonction publique pour vérifier si le personnage bloque et renvoie une valeur booléenne Tout d'abord, le nom de l'action indique le nœud actuel dans une variable de chaîne. Nous pouvons revenir s'il s'agit d'un blocage ou d'un blocage. Et nous aurons également besoin d' une autre fonction pour exécuter l'animation de blocage, indiquant à l'état d'action de passer à l'état de blocage. Ensuite, dans le script du personnage, en haut de la fonction Take Damage. Nous pouvons vérifier si l'animation du personnage est actuellement bloquée et si les dégâts proviennent de l'avant du personnage. En utilisant un produit ponctuel de la direction des dégâts avec le vecteur de base avancé du personnage Si la valeur est positive, les dégâts proviennent de quelque part devant eux. Cela couvrirait cependant un grand angle, une demi-sphère complète devant le personnage. En utilisant quelque chose de plus proche du quart ou de la moitié, nous pouvons le limiter à une forme de cône. Dans ces conditions, l'attaque doit être bloquée avec succès, réduisant le montant des dégâts par la réduction des dégâts du bouclier. Utiliser la fonction max pour le plafonner à un minimum de zéro. Nous pouvons ensuite demander à l'arbre d'animation de jouer l'animation bloquée, et si le montant des dégâts a été complètement réduit à zéro, je reviendrai simplement puisque le personnage ne subit aucun dommage. Essayons-le. Équiper le bouclier et bloquer l'attaque du squelette Les dégâts sont réduits à zéro et l' animation du bloc touché s'exécute. En subissant des dégâts par le côté ou par le dos, le personnage subit toujours des dégâts. Notre personnage est désormais capable de bloquer les attaques avec un bouclier placé de face. Dans la prochaine leçon, nous leur donnerons une arme à distance capable de tirer des projectiles Je te verrai dans la prochaine leçon. 10. Séance photo: Bonjour, mes amis. Dans la leçon précédente, nous avons autorisé notre personnage à bloquer les attaques avec un bouclier. Dans cette leçon, nous allons leur donner une arme arrangée capable de tirer des projectiles Ce pack d'actifs ne contient pas de verrou pour arbalète Je vais donc commencer par en créer un dans la scène des arbalètes En commençant par un nœud en trois D à corps rigide , renommez-le boulon Je vais le positionner là où la base du verrou reposera à l'intérieur de l'arbalète avec son vecteur de base en Z bleu pointant vers l'avant, là où il va tirer Ensuite, je vais ajouter une instance de maillage à trois nœuds D en tant qu'enfant, en la remplissant avec le maillage cylindrique Réduire le rayon et la hauteur, faire pivoter pour qu'il pointe vers l'avant et le positionner vers l' avant le long de l'axe z. Je vais juste lui donner un matériau de base et régler l'albédo pour qu'il soit de couleur marron Ajoutez ensuite un nœud de base en trois D comme autre enfant, afin qu'il soit placé avec la même position et rotation et renommez-le amo socket Reconnectez ensuite la douille Amo à l'arbalète en conservant cette position et cette rotation Replacer le boulon par rapport à la douille AMO, sorte que sa position et sa rotation par rapport à son parent soient désormais nulles Le verrou peut maintenant être transformé en sa propre scène, que je vais placer dans un nouveau dossier pour les projectiles, puis le supprimer de la scène de l'arbalète L'arbalète peut désormais être chargée simplement en ajoutant un boulon en tant qu' enfant de ce nœud Le verrou devra avoir une forme de collision. J'utiliserai une capsule aux mêmes dimensions et à la même position que le cylindre. En élargissant la section du solveur, je devrai activer le moniteur de contacts et régler le nombre maximum de contacts sur une valeur supérieure à zéro Si nous voulons que le verrou entre en collision avec le terrain, il devra masquer la première couche de collision Et je veux que mes boulons bougent lentement pour que je puisse voir ce qu'ils font. Mais je ne veux pas qu'ils tombent à cause de la gravité. Je vais donc régler leur échelle de gravité à zéro. En attachant un script au verrou, nous pouvons le nommer projectile, afin qu'il puisse être utilisé pour d'autres types de projectiles dans notre jeu et l'enregistrer dans le dossier des scripts des objets Dès qu'un verrou est instancié, il est chargé dans l'arbalète Et nous souhaiterons peut-être transmettre des informations concernant le personnage ou l'arme aux munitions pour le moment. Créons une fonction publique à cette fin. Mais pour l'instant, nous allons simplement régler sa propriété de gel sur true, car le corps rigide n'a rien à faire avant le tir de l'arme. Pour tirer le projectile, nous appliquerons une force d'impulsion envoyée par l'arme sous forme de vecteur trois À ce moment, le corps rigide peut commencer appliquer de la physique pour déplacer le verrou dans la scène de jeu, en définissant sa propriété de gel sur False. Nous ne voulons plus que le projectile suive les propriétés de transformation de son parent, l'arbalète Il doit être replacé dans la scène du jeu où il peut se déplacer et agir librement S'il ne pointe pas directement dans la direction, s'il est tiré, nous pouvons dire au verrou de regarder un point dans l'espace correspondant sa propre position globale moins la direction de la force d'impulsion. Appliquez ensuite la force d'impulsion au boulon pour le faire bouger dans cette direction. En reliant le signal saisi par le corps rigide au script, cette fonction sera appelée si le boulon entre en contact avec un objet situé sur la première couche de collision, le terrain. ce cas, le verrou peut rester exactement là où il est entré en contact, rétablissant ainsi sa propriété de blocage sur true, mais en différé puisque cela se produit lors d'une collision. Il est très important que chaque fois que vous implémentez une fonctionnalité dans un jeu qui instancie un grand nombre de nœuds, vous implémentiez également un moyen de les nettoyer. Sinon, vous pourriez vous retrouver avec de très grandes quantités, ce qui entraînerait une baisse de la fréquence d'images et éventuellement un crash de votre jeu. Une pratique courante avec les projectiles consiste simplement à leur donner une durée de vie maximale Ajoutons un nœud temporel à nos projectiles et réglons le compte à rebours une Je vais le régler sur 10 secondes. Ensuite, saisissez une référence à l'heure ou au nœud en utilisant add on ready. Nous démarrerons le chronomètre lors du tir du projectile. S'il ne finit pas par heurter quoi que ce soit, nous voulons tout de même le nettoyer, afin qu'il ne s'envole pas au loin pour toujours. Connecter le signal d'augmentation du temps au script du projectile. Cela indiquera que le projectile sera libéré de la scène de jeu en revenir à la scène de l'arbalète, nous aurons besoin d'un nouveau script pour cette arme Nous pouvons l'appeler arme à distance et la placer dans le dossier des scripts des objets Remplacez le script attaché à cette arme par une arme à distance et donnez-lui une référence au fichier de ressources personnalisé pour l'arbalète Nous pouvons exporter les munitions sous la forme d'une scène pleine à craquer, d'un préfabriqué que nous pouvons utiliser comme plan pour en instancier autant que nécessaire Ensuite, assignez le verrou comme munition pour l' arbalète de l'inspecteur Nous aurons besoin d'une référence à la prise de munitions utilisant at on ready et d'une référence aux munitions actuellement chargées dans l'arme à distance Il peut également être intéressant d' avoir un bonus de dégâts que l'arme ajoutera aux coups de feu tirés sous forme de nombre entier. La force d'impulsion que l'arme applique à ses munitions lorsqu'elle est tirée à flot Je vais utiliser un chiffre faible, comme dix, pour que nous puissions voir facilement les éclairs se déplacer dans les airs, et le masque de collision de nos ennemis pour que les informations puissent être transmises du personnage à l'arme aux munitions. Lors de l'équipement de l'arme, les personnages configurent la boîte à hanches, masque de collision des armes, afin que nous puissions facilement réutiliser la même fonction pour définir la variable du masque Et comme nous l'avons fait avec le shield, nous pouvons ajouter une fonction pour activer le hip box, en ignorant ce paramètre, et simplement revenir. Puisque l'arme n'a pas de boîte à hanches qui lui est propre. L'arme devra être capable de tirer le projectile avec une fonction publique, et nous laisserons le personnage spécifier la direction dans laquelle il souhaite que le projectile aille en tant que paramètre Il suffit à l'arme de transmettre cet appel de fonction à l' ampli, en multipliant la direction par la force de l'arme Définissez ensuite la référence amo chargée null puisque l'arme n' est plus chargée, et une fonction de rechargement, qui instanciera un nouveau verrou, attribuant Ajoutez-le ensuite en tant qu'enfant de la douille Amo, en lui donnant la bonne position et rotation nécessaires pour qu'il tienne bien dans l'arbalète Nous pouvons ensuite transmettre toutes les informations dont les munitions auront besoin avant d' être tirées, comme les dommages causés par les armes et le masque de collision. Allons-y et ajoutons-les en tant que paramètres à la fonction onload dans le script du projectile Le script de notre personnage aura besoin d'une variable pour savoir si l'arme qu'il détient est actuellement chargée. Et deux nouvelles fonctions : recharger et filmer. Rechargez, il suffit de définir la variable sur true, puis de demander à l'arme de main principale de la recharger Pour l'instant, Shoot définira simplement la variable sur False, puis indiquera à l'arme principale de tirer dans une direction, passant le vecteur de base vers l'avant du personnage Si l'arme n'est pas équipée, puisqu'elle est complètement supprimée de l'arbre des scènes, les munitions seront également retirées en même Je vais donc simplement remettre la variable Arme is Loaded à False à ce stade. énumérer les types d'armes, nous aurons besoin de deux entrées supplémentaires pour la gamme d'attaques à une main, qui sera numéro quatre, et attaques à distance à deux mains, numéro cinq Dans la ressource personnalisée sur les arbalètes, je vais changer le script de l'équipement à l'arme Je vais changer son type d'arme à portée d'une main, réduire ses dégâts et repeupler son icône. De même, passez l'arbalète lourde à deux mains. Dans l'arbre d'animation des personnages, nous aurons besoin de plus d'actions pour les attaques à distance. Cette machine à états est déjà assez volumineuse et désordonnée. Je vais donc intégrer les attaques à distance dans une autre machine à états En passant à cette machine à états, si les personnages attaquent animation est de quatre ou cinq, qu'ils veulent attaquer, ne sont pas touchés et qu'ils n'esquivent pas Revenez ensuite au mode veille à la fin de l'animation. Et je vais mélanger les deux transitions avec un peu de fondu croisé. À l'intérieur de la zone de tir pour attaquer State Machine, nous pouvons ajouter des animations pour le tournage et le rechargement Aussi bien pour les attaques à distance à une main que pour les attaques à deux mains. Il suffit de jouer le bon jeu une seule fois , puis de revenir à la machine à états d'action. Ils feront donc tous la transition à la fin. Pour passer à une main l' animation de l'attaque doit être réglée sur quatre. Et le jeu à deux mains est réglé f. La valeur de l'arme chargée déterminera si les animations de tir ou de rechargement sur f. La valeur de l'arme chargée déterminera si les animations de tir ou de rechargement seront jouées Maintenant que les animations peuvent être jouées par l'arbre d'animation, nous avons besoin des animations pour appeler des fonctions dans le script du personnage. Pendant le tournage de l'animation, nous ajouterons une méthode, une piste d'appel et un gommage à l'image avant que le personnage ne recule devant le projectile tiré Ajoutez ensuite une image clé pour appeler la fonction de prise de vue. De même, lors de l'animation de rechargement, nous essaierons de sélectionner une image lorsque le personnage aura fini de recharger l'arme Et ajoutez une image clé à la piste de la méthode d'appel pour recharger réellement l'arme Si nous voulons que ces animations empêchent le personnage d'effectuer d' autres actions, nous devons définir une variable booléenne, comme nous l'avons fait pour les attaques Je vais simplement réutiliser la variable d'attaque. Et répétez également l'opération pour les animations à distance à deux mains . Essayons-le. Nous pouvons équiper le personnage d'une arbalète , et en appuyant une fois sur le bouton d' attaque, nous lui demanderons de charger l' arbalète avec un En appuyant une seconde fois sur le bouton d'attaque, ils tirent l'arbalète vers l'avant, et le verrou jaillit jusqu'à ce qu' il touche un objet dans l'environnement, où il s'arrête et se détruit au bout de 10 secondes. Nous avons maintenant besoin des boulons pour infliger des dégâts aux ennemis. revenir à la scène du verrou, nous devrons ajouter une case de frappe au verrou. La zone de frappe doit avoir la forme d'une collision. Je vais utiliser la sphère. Je vais le positionner à l'autre bout du boulon et lui donner un rayon plus petit. Tout comme nos autres boîtiers branchés, il n'est pas nécessaire qu'il soit surveillé ou qu'il soit encore équipé d'un masque anticollision. En saisissant une référence à la boîte à hanches en utilisant at on ready, exportons également une variable indiquant l'endommagement des boulons Je vais utiliser une valeur par défaut de un. Lorsque le personnage place le verrou dans l'arbalète, c'est personnage place le verrou dans l'arbalète, une bonne occasion transmettre des informations, telles que les bonus de dégâts et le masque de collision Le bonus de dégâts infligés par les armes peut être ajouté aux dégâts infligés par les boulons, et la couche de collision de la boîte à hanches peut être réglée sur la couche de collision ennemie du personnage. Lorsque le projectile est tiré, nous pouvons demander à la boîte à hanches de commencer à surveiller les nichoirs ennemis En connectant la zone de la hanche signal est entré dans le script du projectile Nous pouvons indiquer à la boîte à blessures que ce projectile a touché pour indiquer à son personnage parent de subir des dégâts À partir de la direction de la position globale des cases Hurt moins la position globale du Bolt normalisée. Le verrou peut ensuite être retiré de la scène. Et si le verrou touche le terrain, il ne devrait plus être surveillé pour infliger des dégâts Nous le réglerons donc sur un faux différé. Dans le script du personnage, je voudrais m' assurer que lorsque le personnage est bloqué sur une cible, le projectile est tiré directement sur cette cible Ainsi, la fonction de tir se divise en deux comportements différents selon que le personnage est bloqué ou non sur une cible, appelant une fonction distincte pour tirer sur une cible, en passant la cible comme argument. Mais l'arme ne doit tirer sur la cible verrouillée que si le personnage lui fait face. Nous pouvons donc vérifier si le produit scalaire du vecteur de base avancé des personnages et de la différence normalisée leurs positions globales est un nombre positif Plus c'est positif, plus ils se ressemblent, plus le personnage est tourné vers eux. Je dirais qu'un objet supérieur à 0,75 est suffisamment proche pour atteindre la cible verrouillée Dans le script d'arme à distance, donner une définition du tir sur cible, accepter une cible comme paramètre Nous pouvons maintenant calculer la direction sous la forme de la différence entre les positions d' affaissement normalisée et multipliée par Comme cela utilisera la position gubale de l' arme, non la position gubale du personnage, la direction sera plus précise Et je vais ajouter 1 mètre à la position de la cible pour ne pas viser ses pieds. Essayons-le. En m'équipant d'une arme et en m'accrochant à une cible, je vais d'abord faire face sur le côté, et le projectile continue de tirer vers l'avant, puisque le personnage n'est pas face à En se déplaçant pour faire face à la cible et en tirant un deuxième éclair, il tire cette fois directement sur la cible et inflige des dégâts. Nous avons maintenant des projectiles tirés à distance qui touchent des ennemis ou Dans la prochaine leçon, nous allons autoriser les ennemis à détecter les joueurs et à riposter. Je te verrai dans la prochaine leçon. 11. Ennemi: Bonjour, mes amis. Dans la leçon précédente, nous avons ajouté des attaques à distance qui tirent des projectiles Dans cette leçon, nous allons autoriser les ennemis à détecter, poursuivre et attaquer le personnage du joueur. Dans la scène du cimetière, nous avons ajouté un simple nœud qui indique l'ennemi d'attaquer constamment Supprimons cela et commençons à créer une version plus complexe pour n' attaquer que lorsque le personnage du joueur est à portée d'être touché. Dans la scène des sbires squelettes, nous y ajouterons un nœud enfant de type nœud trois D, car il devra accéder à trois positions et rotations en D. Je vais appeler ça de l'agressivité. Ajoutez ensuite un nœud de zone 3 D, qui représentera la portée d'attaque de l' ennemi. Je vais lui donner une forme de collision et utiliser une sphère. En ajustant la taille de la sphère pour qu'elle soit un peu plus grande, je lui donnerai un rayon de 1 mètre, puis je la positionnerai à 1 mètre du sol et à 1 mètre vers l'avant. La zone de portée d'attaque surveillera les collisions masquant le coffre du joueur. Attachons un script à ce nœud et placons-le dans le dossier des scripts ennemis. Le but de ce script étant de contrôler un personnage de la même manière que le nœud du gestionnaire d'entrées du joueur, nous aurons besoin d'une référence au personnage contrôlé par ce nœud Compte tenu de la façon dont je structure mon arbre de scène, ce nœud sera toujours l'enfant direct du nœud du personnage Je peux donc accéder au personnage en appelant get parent En connectant les signaux de zone entrée et de zone sortie au script, je vais renommer les paramètres et leur donner des types pour Lorsque la boîte à blessures du personnage du joueur entre dans la zone d'attaque, nous voulons dire à l' ennemi d'attaquer. Et lorsque la boîte Hert sort de la zone d'attaque, nous pouvons dire à l' ennemi de ne pas attaquer Nous pouvons enregistrer cette branche en tant que scène à part entière et l'enregistrer dans le dossier des scènes ennemies. Supprimez-le ensuite de cette scène ennemie. E De retour dans la scène du cimetière, nous pouvons associer notre nœud d'agression ennemi à l'un ou à l'ensemble de nos ennemis pour qu'ils attaquent automatiquement le personnage du joueur s'il entre dans la zone d'attaque Essayons-le. Les ennemis n'attaquent pas encore, mais nous attaquerons si nous entrons dans leur zone d'attaque et nous nous arrêterons lorsque nous la quitterons. Ensuite, nous allons permettre aux ennemis de voir le personnage du joueur de plus loin. En ouvrant la scène du nœud d' agression, nous pouvons ajouter un autre nœud de zone en trois D pour représenter la vision d'un ennemi. En ajoutant une forme de collision à cette scène, j'utiliserai une autre sphère avec un rayon beaucoup plus grand. Je vais utiliser 5 mètres et le positionner de manière à ce qu'il devance l'ennemi et un peu au-dessus du sol. Cette zone peut surveiller couche de collision du personnage du joueur. J'utiliserai la couche 9. Ajoutez ensuite un nœud à trois points en D pour leur ligne de visée et déplacez-le vers le haut hors du sol. Cela recherchera la même couche que le champ de vision, mais sera également obstrué par le terrain Comme j'ai utilisé la couche 9, qui correspond au corps du personnage et non à la boîte en T, je vais relier les signaux entrés et sortis sur le corps au script d'agression Lorsqu'un corps entre dans le champ de vision, je le stocke dans une variable, nommons-le cible de type personnage corps trois D. Mais nous devons également confirmer qu' il a également une ligne de visée claire avant de devenir agressif. Nous aurons donc besoin d'une référence au casting. Et nous pouvons enregistrer si l'ennemi a vu le joueur ou non dans une variable booléenne Faisons également référence au champ de division de l'ennemi. R. En utilisant la fonction de processus, nous pouvons commencer par vérifier si la valeur de la cible a été définie. S'il est nul, l'ennemi ne peut pas voir le personnage du joueur. Nous devrions simplement rentrer. Si l'ennemi n' a pas encore vu le joueur, nous pouvons vérifier sa ligne de visée par rapport à la cible. Définissez la position cible du raycast comme étant la différence entre leurs positions globales, en ajoutant un mètre au-dessus du sol Après avoir forcé le raycast à se mettre à jour s'il entre en collision avec un objet et si l'objet avec lequel il entre en collision est la cible, la ligne de visée n'est pas obstruée Nous pouvons définir la variable has seen player sur true. Si la valeur de cette variable est vraie, le comportement de l'ennemi changera et nous lui demanderons de poursuivre le personnage du joueur. Lorsque le personnage du joueur quitte le champ de vision de l'ennemi, si le corps est la cible et que l'ennemi n'a pas encore vu le joueur, nous n'avons plus besoin de vérifier sa ligne de visée, nous pouvons donc définir la cible sur zéro Ce nœud d'agression est un enfant du nœud personnage, qui ne tourne pas. Le champ de vision et la portée d' attaque ne changeront donc pas en fonction de la configuration du personnage. Nous pouvons utiliser la référence du caractère pour saisir la rotation de l'anneau, accéder à la propriété y et l'affecter à la rotation y de ce nœud. Il suivra donc la même rotation. Nous voudrions peut-être aussi trouver un moyen de dire à cet ennemi d'arrêter de poursuivre le personnage du joueur. Dans ce cas, nous pouvons définir la cible sur null, avoir vu la cible sur false et dire à ce personnage de se déplacer sans direction. Le bon moment pour appeler cette fonction serait lorsque l'ennemi meurt. Donc, remplacez la fonction Ready. Nous pouvons connecter le signal mort de ce personnage à la fonction d'arrêt. Lorsque l'ennemi voit le personnage du joueur pour la première fois, nous pouvons également associer le signal de mort de la cible à la fonction d' arrêt pour empêcher l'ennemi d'essayer de tuer le personnage du joueur qu'il est déjà mort. J'utiliserai également cette même fonction pour désactiver la vision de cet ennemi, en définissant sa propriété de surveillance sur False. Pour que l'ennemi puisse se déplacer vers le joueur, nous devons d'abord apporter quelques modifications à notre scène de niveau. Ajoutons un nœud en trois D de la région de navigation au niveau. Reparentez ensuite tous les nœuds qui seront utilisés pour générer notre carte de navigation en tant qu'enfants de ce nœud, y compris le sol et les obstacles. fois cela fait, sélectionnez le nœud de la région de navigation et remplissez le maillage de navigation avec un nouveau maillage de navigation Cliquez ensuite sur le bouton du maillage de navigation Bake. Le maillage de navigation couvrira le terrain avec des triangles qui formeront une zone où les personnages pourront marcher. En élargissant la ressource de maillage de navigation, nous pouvons voir ses propriétés. La seule section préoccupante à l' heure actuelle est la section des agents. Les agents sont nos personnages qui utiliseront ce maillage de navigation pour se déplacer dans la scène. En jetant un coup d'œil aux capsules de collision de nos personnages, je leur ai donné une hauteur de 2,6 mètres et un rayon de 0,75 mètre Je vais copier ces valeurs dans la hauteur et le rayon de l'agent dans la ressource de mesure de navigation, puis redéfinir le maillage de navigation Le maillage laisse désormais plus d'espace entre les murs et les obstacles. Pour utiliser la région de navigation, nos personnages auront tous besoin d' un autre nœud attaché à eux, un nœud tridimensionnel de l'agent de navigation. Assurez-vous d'en attacher un à chaque personnage. Saisir une référence à ce nœud à l'aide de la commande add on ready. Nous pouvons ensuite écrire une fonction dans le script de caractères, qui peut être utilisée pour indiquer à n'importe quel personnage de naviguer vers n'importe quel endroit du maillage de navigation pour une raison quelconque. C'est également très utile pour de nombreuses choses en dehors du combat. En acceptant une position cible comme vecteur trois, nous allons définir la position cible de l' agent de navigation comme étant la même position. L'agent de navigation utilisera automatiquement le maillage de navigation, auquel est affectée la même couche de navigation, pour créer un chemin permettant de se rapprocher le plus possible de l' emplacement cible. appelant les agents à obtenir la position du chemin suivant, nous allons renvoyer le premier point de chemin le long de ce chemin sous la forme d'un vecteur trois. Nous pouvons ensuite soustraire la position globale actuelle du personnage pour obtenir un vecteur pointant de l'endroit où nous nous trouvons vers la première position le long du chemin Si nous le multiplions par 101 pour supprimer la composante verticale, normalisons ce vecteur. Il est désormais fonctionnellement équivalent à un vecteur d'entrée produit par notre script de gestion des entrées du lecteur lorsque le joueur incline le stick analogique ou utilise les touches WASD Nous pouvons donc l'attribuer à la variable de direction d'entrée. Et le processus physique s'occupera du reste, demandant au personnage de suivre ce chemin, qui le guidera vers sa cible. Ce serait une bonne idée de transférer tout ce qui arrive à un personnage lorsqu'il meurt dans une fonction publique au cas où autre chose que le fait de subir des dégâts pourrait entraîner sa mort. Quand un personnage meurt, il faut lui dire d'arrêter de bouger. Et lorsqu'on leur demande de bouger ou d'agir, nous devons ignorer ces demandes si le personnage est mort en revenant. en revenir au scénario d'agression, il suffit de dire à l'ennemi de se diriger vers sa cible une fois qu'il l'a vue. Avant de l'essayer, choisissons un ennemi. Je vais utiliser le guerrier squelette et sélectionner son nœud 3D Agent de navigation. Dans la section D Bug, cliquez sur le bouton d'activation pour voir le chemin affiché dans le jeu l'approche du premier squelette, dès que nous entrons dans son champ de vision, la ligne de visée confirme immédiatement qu'il peut nous voir, et l'agent de navigation trouve un chemin pour que l'ennemi puisse marcher vers nous. Alors, attaque-nous. En battant cet ennemi, cette fois, attirons l'attention du voleur Comme ils se trouvent derrière la pierre tombale, ligne de visée n' est pas confirmée et l'ennemi reste caché Et si nous nous approchons du guerrier, nous pouvons courir autour de la tombe ouverte voir comment l'agent de navigation mettra automatiquement à jour le chemin en temps réel, afin de contourner le chemin le plus court possible pour atteindre le joueur. Nous voudrions peut-être aussi que nos ennemis soient capables de manier des armes Revenons à la scène du cimetière, attachons un autre nœud de base à l'un de nos ennemis et nommons-le et nommons-le En joignant un script à ce nœud, je le mettrai dans le dossier des scripts de l' ennemi. Il suffit de saisir une référence au nœud parent, le personnage, et d'exporter une arme à équiper pour ce personnage. Ensuite, dans la fonction Prêt, dites au personnage de manier l'arme. Je vais demander à mon guerrier squelette de s'équiper d'une belle hache. Copiez et collez ensuite ce nœud sur un autre ennemi et remplacez l' arme par autre chose. Je vais donner des couteaux au voleur. d'attache osseuse devront être ajoutés à chacune de nos scènes ennemies nœuds d'attache osseuse devront être ajoutés à chacune de nos scènes ennemies. En suivant leur fente gauche et leur fente droite. Nous pouvons ensuite remplir le tableau de prises d'équipement des personnages avec ces nœuds à utiliser lors de l'équipement Enfin, ce serait bien de ne pas avoir à recharger le jeu à notre mort. Connectons donc le signal mort du personnage du joueur au script du game manager. Une fois passé au noir, je vais simplement demander à l'arbre des scènes de recharger la scène en cours, en rétablissant le tout comme il était lors du premier je vais simplement demander à l'arbre des scènes de recharger la scène en cours, en rétablissant le tout comme chargement de la scène Essayons-le. Le guerrier squelette est équipé du grand A et utilise les animations d' attaque à deux mains. Quand on meurt, toute la scène est rechargée. Et pour affronter le voleur cette fois, ils sont équipés de couteaux et utilisent des animations à deux roues Nous avons maintenant un système de combat complexe dans notre jeu avec une variété de mécanismes qui peuvent être ajustés en fonction des besoins de votre jeu.