Dans cette partie du tutoriel, vous allez créer un PNJ ennemi qui détecte et poursuit le joueur, et lui inflige des dégâts. L'ennemi peut lui aussi subir des dégâts et se déplacer dans l'environnement pour éviter les obstacles à l'aide d'un maillage de navigation.
Vous allez commencer par créer la logique de l'ennemi à l'aide du système de programmation visuelle Blueprint, comme dans les tutoriels précédents. Vous créerez ensuite le maillage de navigation pour définir les zones dans lesquelles les personnages contrôlés par l'IA peuvent se déplacer pendant le jeu.
Avant de commencer
Assurez-vous de bien comprendre les sujets abordés dans la section précédente du document Concevoir une aventure de type énigme :
Blueprints et fonctions de blueprint
Vous aurez besoin des ressources suivantes décrites dans la page Créer une clé :
Bibliothèque de fonctions de blueprint
BPL_FPGame
Créer un maillage de navigation pour la navigation de l'ennemi
Avant d'ajouter l'ennemi à un niveau et de faire en sorte qu'il poursuive le joueur, vous devez construire le NavMesh que l'IA ennemie utilisera pour naviguer dans le niveau.
NavMesh, qui est l'abréviation anglaise de Navigation Mesh (maillage de navigation), définit les zones du niveau dans lesquelles l'IA peut se déplacer. En créant un maillage de navigation dans ce tutoriel, vous allez définir une zone dans laquelle l'ennemi peut se déplacer pour poursuivre le joueur.
Pour ajouter le maillage de navigation à votre niveau, procédez comme suit :
Dans l'éditeur de niveau de l'Unreal Editor, accédez à la barre d'outils principale, cliquez sur le bouton Créer, accédez à Volumes, puis sélectionnez Volume de limite de maillage de navigation. Une zone navigable pour l'IA est ainsi créée dans votre projet.
À l'aide des outils de transformation, déplacez le maillage de navigation à intersecter avec le sol dans votre niveau.
Appuyez sur la touche P de votre clavier pour activer ou désactiver la vue de débogage. Utilisez cette touche pour afficher les détails du maillage de navigation dans le hublot du niveau, notamment les zones navigables du niveau, ainsi que les informations de débogage sous forme de texte sur le côté gauche du hublot.
Si les informations de débogage contiennent le message "Le maillage de navigation doit être recréé", accédez à la barre de menus et sélectionnez Générer > Générer les chemins. Cette action permet de recréer votre maillage de navigation.
Continuez à déplacer le maillage de navigation et à en modifier l'échelle (touches W et R de votre clavier) pour modifier ses limites. Ajustez ce volume à votre convenance.
Assurez-vous que la partie inférieure du maillage de navigation est suffisamment basse pour inclure les éléments de sol en retrait et que la partie supérieure du maillage de navigation est suffisamment élevée pour s'adapter à la taille de l'ennemi.
Si vous utilisez le niveau d'exemple du tutoriel, créez et ajustez deux volumes de limites de maillage de navigation de façon à ce qu'ils remplissent le couloir 3 et la pièce 3.
Lorsque vous changez l'échelle du maillage de navigation et le déplacez, les zones vertes s'agrandissent en fonction de la taille de la boîte englobante, sauf en présence d'obstacles comme des cubes. Toutes les parties coupées en rouge sont inaccessibles par l'IA dans votre jeu.
Si l'Unreal Editor inclut dans le maillage de navigation un élément qui ne devrait pas s'y trouver, sélectionnez cet objet de niveau de maillage et désactivez l'option Influence permanente sur la navigation dans le panneau Détails.
Créer un ennemi
Vous allez créer l'ennemi à partir de la classe Personnage, car elle comprend déjà des fonctionnalités de déplacement et d'animation adaptées à un adversaire humanoïde. La classe Personnage étend en réalité le pion, qui est l'"acteur contrôlable" le plus général utilisé pour des éléments comme les véhicules, les caméras ou les créatures non humanoïdes. Pour créer des ennemis en forme humaine, la classe Personnage est un excellent point de départ.
Étant donné que vous créez ce personnage de toutes pièces, vous ajouterez un maillage pour représenter visuellement l'ennemi et lirez une animation à l'aide d'un blueprint d'animation. Le blueprint d'animation étant fourni dans les fichiers du projet, il n'est pas nécessaire de le créer de toutes pièces, mais il est important d'apprendre comment l'intégrer dans le blueprint du personnage ennemi.
Commencez par créer le blueprint d'ennemi. Procédez comme suit :
Dans le navigateur de contenu, accédez à Contenu > AdventureGame > Concepteur > Blueprints > Personnages.
Faites un clic droit dans une zone vide du navigateur de contenu, puis cliquez sur Classe de blueprint.
Dans la nouvelle fenêtre, sélectionnez Personnage comme classe de base.
Nommez cette classe
BP_Enemy, puis ouvrez-la dans l'éditeur de blueprint en double-cliquant dessus.
Lorsque vous créez une classe de blueprint, vous choisissez une classe parente à partir de laquelle construire. Cette classe parente dispose déjà de fonctionnalités intégrées. Par exemple, si vous avez créé des blueprints à partir de la classe Acteur, vous avez commencé par une transformation et la capacité de contenir des composants et d'exécuter une logique. En commençant par la classe Personnage, vous bénéficiez également d'une prise en charge des déplacements, des collisions et des animations. La classe de base s'utilise de la même façon qu'un modèle. Lorsque vous ajoutez une fonctionnalité, vous étendez cette classe de base.
Une fois la fenêtre du blueprint BP_Enemy ouverte, accédez à l'onglet Hublot et observez le panneau Composants. Le composant Mouvement de personnage (CharMoveComp) se trouve en bas de la liste. Toutes les classes de personnage incluent un composant de déplacement de personnage. Cliquez sur ce composant et examinez le panneau Détails pour voir tous les paramètres qu'il contient. Vous modifierez certains de ces paramètres lorsque vous créerez les ennemis dans votre projet.
Ajouter un modèle 3D à l'ennemi
Votre personnage dispose également d'un composant de maillage, qui n'est pas un maillage statique, mais un maillage squelettique. Les maillages statiques sur lesquels vous avez travaillé jusqu'à présent sont des modèles 3D fixes qui ne se déplacent pas, tandis qu'un maillage squelettique dispose d'un squelette interne qu'il est possible d'animer et de déformer.
Commencez par configurer le maillage et les animations du personnage. Procédez comme suit :
Sélectionnez le composant Maillage et examinez le panneau Détails. Recherchez la catégorie Maillage et cliquez sur le menu déroulant en regard de la ressource de maillage squelettique. Dans la liste, recherchez le modèle
SKM_Manny_Simpleet sélectionnez-le. Le modèle Manny est ainsi affecté au blueprint.Dans le panneau Détails, accédez à la catégorie Animation. Cliquez sur le menu déroulant en regard de Classe d'animation, puis affectez le blueprint d'animation
ABP_Unarmed. Le personnage ennemi doit maintenant jouer une animation d'inactivité dans l'onglet Hublot.Modifiez le blueprint d'animation pour qu'il fonctionne correctement avec l'ennemi :
Dans la propriété Classe d'animation du maillage ennemi, cliquez sur Atteindre la ressource dans le navigateur de contenu en regard de
ABP_Unarmed.Double-cliquez sur le blueprint d'animation
ABP_Unarmedpour l'ouvrir.Accédez au groupe de logique situé après la broche Then 1 du nœud Sequence.
Dans la mesure où vous ne souhaitez pas que le contrôle d'accélération empêche les personnages ennemis de bouger, supprimez le lien qui relie le nœud And et le nœud Set Should Move.
Reliez la broche de sortie du nœud Greater (>) à la broche Should se déplacer, en ignorant le contrôle d'accélération.
Compilez, enregistrez et fermez le blueprint.
Dans le hublot, une forme de capsule cylindrique entoure le personnage ennemi. Il s'agit d'une représentation visuelle du composant de capsule qui détecte les collisions avec d'autres objets, y compris le sol. Le maillage du personnage ayant une forme plus complexe, le cylindre de collision simple fluidifie la forme pour améliorer les performances de détection de collision.
Le maillage est décalé et n'est pas aligné sur la capsule. Pour aligner le maillage du personnage sur le composant de capsule, déplacez le personnage vers le bas afin que ses pieds touchent la partie inférieure du composant de capsule.
Pour aligner le maillage du personnage sur son volume de collision, procédez comme suit :
Sélectionnez à nouveau le composant Maillage pour mettre en évidence le modèle 3D.
Dans le panneau Détails, utilisez le champ Emplacement de la catégorie Transformation pour modifier l'axe Z, qui est le dernier champ bleu. Définissez la valeur sur
-96.
Les deux composants sont désormais centrés à l'origine, afin que l'ennemi ne flotte pas au-dessus du sol dans le jeu.
Enfin, vous verrez que le personnage dispose d'un composant de flèche (flèche). La flèche indique la direction vers l'avant du blueprint. Assurez-vous que cette flèche correspond au sens d'orientation du maillage, afin que le personnage se déplace dans la bonne direction.
Pour orienter le maillage du personnage vers l'avant, procédez comme suit :
Sélectionnez à nouveau le composant Maillage. Utilisez le gadget de rotation ou la catégorie Transformation du panneau Détails pour faire pivoter le personnage de 90° sur l'axe Z. La valeur de sa dernière rotation doit être de -90.
Modifier le matériau du modèle 3D
Avant de passer à la création de fonctionnalités, définissez la couleur du modèle de l'ennemi sur le rouge. La couleur rouge évoque davantage un ennemi (contrairement à la couleur blanche actuelle, associée au joueur).
Pour attribuer une couleur différente au personnage ennemi, procédez comme suit :
La section Matériaux du panneau Détails comporte deux éléments :
Le matériau
MI_Manny_01_Newa une incidence sur divers emplacements du modèle ennemi, notamment les bras supérieurs, les jambes et la tête.Le matériau
MI_Manny_02_Newa une incidence sur les avant-bras et le torse.
En regard de l'élément 0, cliquez sur le bouton Parcourir dans le navigateur de contenu qui ressemble à un dossier et une loupe. Le dossier contenant ce matériau s'ouvre dans le navigateur de contenu. Le deuxième matériau,
MI_Manny_02_New, se trouve également dans ce dossier.Faites un clic droit sur la ressource
MI_Manny_01_New, puis cliquez sur Créer une instance de matériau.Nommez l'instance de matériau
MI_Enemy_01et double-cliquez dessus pour l'ouvrir.Dans le panneau Détails, développez 01 - BaseColor et activez la propriété Teinte de peinture.
Cliquez sur le nuancier en regard de la propriété Teinte de peinture et sélectionnez une couleur. Dans ce tutoriel, nous utilisons sRVB hexadécimal =
F60E6EFF.Cliquez sur Enregistrer et fermez la fenêtre.
De retour dans le navigateur de contenu, faites un clic droit sur
MI_Manny_02_New, puis cliquez sur Créer une instance de matériau.Nommez cette instance de matériau
MI_Enemy_02et répétez les étapes précédentes pour changer la couleur et enregistrer la ressource.
Après avoir répété ces étapes, vous devriez disposer de deux nouvelles instances de matériau : MI_Enemy_01 et MI_Enemy_02.
Ensuite, pour attribuer ces matériaux au personnage ennemi, procédez comme suit :
Dans le blueprint
BP_Enemy, accédez au panneau Détails, puis à la section Matériaux.Cliquez sur le menu déroulant en regard de l'élément 0 et sélectionnez le nouveau matériau que vous avez créé, à savoir
MI_Enemy_01.Pour l'élément 1, remplacez-le par le matériau
MI_Enemy_02.
Ajouter un ennemi au niveau
Ajoutez un ennemi à votre niveau pour examiner son apparence et son comportement jusqu'à présent.
Dans le navigateur de contenu, faites glisser le blueprint d'ennemi dans le hublot de niveau et placez-le devant le joueur.
Lorsque vous jouez, vous devriez voir l'ennemi s'animer avec une animation d'inactivité.
Configurer l'ennemi au démarrage du jeu
L'ennemi étant prêt visuellement, vous pouvez créer la fonctionnalité de gameplay. Vous allez commencer par configurer les propriétés nécessaires pour l'ennemi quand il apparaît.
Pour définir la vitesse de déplacement de l'ennemi au démarrage du jeu, procédez comme suit :
Dans la fenêtre de l'éditeur de blueprint
BP_Enemy, accédez à l'onglet Graphique d'événements. Par défaut, trois événements sont disponibles : Événement BeginPlay, Événement ActorBeginOverlap et Tick d'événement. Sélectionnez ActorBeginOverlap et supprimez-le, car il n'est pas nécessaire dans le cadre de ce tutoriel.À l'aide du panneau Composants, faites glisser le composant Déplacement du personnage dans le graphique d'événements. Un nœud Character Movement est ainsi créé. Ce nœud de composant vous permet de vérifier ou de modifier les propriétés de ce composant à partir du graphique.
Faites glisser la broche du nœud Character Movement et créez un nœud Set Max Walk Speed.
Faites un clic droit sur la broche verte Max Walk Speed du nœud Set et sélectionnez Promouvoir vers la variable.
Une nouvelle variable est créée dans le panneau My Blueprint, sous la liste des variables.
Renommez cette variable
MaxSpeed. Cliquez sur l'icône d'œil en regard de la variable pour la convertir en variable publique et modifiable.Définissez sa catégorie sur Configuration.
Compilez le blueprint puis, dans le panneau Détails, définissez la valeur par défaut du paramètre Vitesse max. sur
200.Veillez à toujours définir une valeur par défaut pour vos variables modifiables. Si vous oubliez de modifier sa valeur dans l'éditeur de niveau et que la valeur par défaut est définie sur 0, l'ennemi ne peut pas se déplacer.
Reliez l'événement BeginPlay au nœud Set Max Walk Speed.
Ensuite, deux variables permettent de suivre le nombre de PV de l'ennemi. TotalHP, une variable modifiable pour chaque instance, détermine les points de vie initiaux de l'ennemi. CurrentHP suit le nombre de PV de l'ennemi pendant le jeu lorsqu'il subit des dégâts infligés par le joueur ou l'environnement.
Pour définir les PV de l'ennemi, procédez comme suit :
Dans la liste des variables, ajoutez une nouvelle variable appelée
CurrentHPde type Float.Faites glisser la variable CurrentHP de la liste Variables dans le graphique d'événements et sélectionnez l'option Définir les PV actuels. Faites glisser la broche Exec du nœud Set Max Speed et reliez-la à la broche Exec du nœud Set Current HP.
Sur le nœud Set Current HP, faites un clic droit sur la broche float de CurrentHP et cliquez sur Promouvoir vers la variable.
Renommez cette variable PV totaux. Assurez-vous qu'elle est de type Float et cliquez sur l'icône d'œil pour la rendre publique et modifiable. Dans le panneau Détails, définissez sa catégorie sur Configuration. Compilez le blueprint et définissez la valeur par défaut sur
100.Reliez les broches Exec entre les nœuds Set.
Étant donné que vous allez effectuer de nombreuses actions avec le personnage joueur dans ce graphique d'événements, enregistrez une référence au joueur sous forme de variable.
Pour configurer une variable pour le personnage joueur, procédez comme suit :
Dans la liste des variables, créez une nouvelle variable appelée
PlayerRefet définissez son type sur Personnage (référence d'objet).Il est plus efficace de créer une variable de référence pour l'objet de personnage afin d'optimiser les performances de votre projet que d'appeler la fonction Obtenir le personnage joueur chaque fois que vous devez créer une référence au joueur.
Après le nœud Set Current HP, reliez un nœud Set PlayerRef.
Pour sa broche d'entrée Player Ref, reliez un nœud Get Player Character. Vérifiez que la valeur Index de joueur est définie sur 0. Il s'agit de l'index par défaut du premier personnage joueur qui apparaît dans le niveau.
Faire en sorte que l'ennemi poursuive le joueur
Vous allez ensuite créer la logique qui vous permet de déplacer l'ennemi vers le joueur. Pour cela, créez un événement personnalisé. Appelez des événements personnalisés depuis n'importe quel emplacement du blueprint pour déclencher et exécuter une logique.
Pour créer un événement personnalisé qui déclenche une action de déplacement, procédez comme suit :
Faites un clic droit n'importe où dans le graphique d'événements et saisissez
Événement personnalisédans le champ de recherche. Cliquez sur l'option Ajouter un événement personnalisé dans la liste et appelez cet événement MoveToPlayer.Faites glisser la broche du nœud d'événement MoveToPlayer , puis recherchez et créez un nœud IA MoveTo. Ce nœud est une action que les pions disposant d'un contrôleur IA utilisent pour se déplacer vers un emplacement spécifique. Dans ce cas, il permet de déplacer l'ennemi vers le joueur.
De la même façon que votre personnage joueur est contrôlé par un contrôleur de joueur, les PNJ peuvent être contrôlés par un contrôleur IA. Pour afficher les paramètres Possession automatique IA dans le blueprint
BP_Enemy, sélectionnez le composant racine et accédez à la catégorie Pion du panneau Détails.Sur le nœud IA MoveTo, faites glisser la broche Pawn et saisissez
Selfdans le champ de recherche. Sélectionnez Obtenir une référence à soi pour créer un nœud qui fait référence à l'acteur de ce blueprint dans le jeu.Faites glisser la broche Target Actor du nœud IA MoveTo et créez un nœud Get PlayerRef.
Définissez le paramètre Rayon d'acceptation sur
10. Ce paramètre détermine la distance (en centimètres) à laquelle l'ennemi considère qu'il est arrivé à destination. Il vous donne plus de contrôle que le paramètre Arrêter lors du chevauchement.
Dans ce cas, vous utilisez le nœud Self pour définir cet ennemi en tant que pion devant se déplacer. Ensuite, vous définissez le joueur comme l'acteur cible, c'est-à-dire la cible vers laquelle le pion se déplace.
Le nœud IA MoveTo dispose des événements À la réussite et À l'échec . Ces événements définissent ce qui se passe si l'ennemi atteint le joueur ou s'il échoue.
Pour définir ce qui se passe après que l'ennemi se déplace, procédez comme suit :
Dans le nœud IA MoveTo, faites glisser la broche On Success et créez un nœud Delay.
Faites un clic droit sur la broche Duration du nœud Delay et sélectionnez Promouvoir vers la variable.
Nommez cette variable WaitAtDestination et définissez son type sur Float.
Compilez le blueprint et remplacez la valeur par défaut de WaitAtDestination par
5. Cliquez sur l'icône d'œil pour rendre cette variable modifiable, puis définissez sa catégorie sur Configuration.Dans le graphique d'événements, faites glisser la broche Exec du nœud Delay et créez un nœud Move To Player. Ainsi, l'ennemi continue de poursuivre le joueur s'il s'éloigne, mais après un délai qui permet au joueur de prendre un peu de distance.
Faites glisser la broche On Fail du nœud AI MoveTo, puis créez un nouveau nœud Delay.
Faites glisser la broche Completed du nœud Delay et créez un nœud Move To Player. Laissez le paramètre Durée sur 0,2. De cette façon, l'ennemi continue de se déplacer s'il n'a pas encore atteint le joueur.
Dans le groupe de logique Événement BeginPlay, à la fin de cette séquence et après le nœud Set Player Ref, reliez un nœud Move To Player pour déclencher cet événement. L'ennemi se déplace ainsi en début de partie afin que vous puissiez tester ses mouvements.
Enregistrez et compilez le blueprint.
Votre graphique d'événements doit maintenant ressembler à ceci :
Tester le déplacement de l'ennemi
Dans votre niveau, déplacez votre acteur ennemi pour qu'il se trouve dans les limites du maillage de navigation, c'est-à-dire sur les zones vertes.
Sélectionnez l'acteur BP_Enemy dans le hublot de niveau ou dans l'organiseur. Les variables que vous avez ajoutées dans le blueprint s'affichent dans le panneau Détails, dans la section Configuration. Vous pouvez modifier ces valeurs pour répondre aux besoins de votre projet, ou activer l'option Déboguer la détection pour permettre le dessin de débogage du tracé de ligne.
Jouez à nouveau à votre niveau et observez le comportement de l'ennemi. Il doit marcher en direction du joueur, s'arrêter lorsqu'il l'atteint, attendre 5 secondes, puis tenter à nouveau de se diriger vers lui.
Si quelque chose ne fonctionne pas comme prévu, vérifiez les valeurs des variables que vous avez créées dans le blueprint BP_Enemy de la scène. Si vous ne définissez pas les valeurs de vitesse maximale ou de distance maximale de détection, l'ennemi ne se déplace pas. Il en va de même si les valeurs sont trop faibles.
Infliger des dégâts au joueur
Maintenant que l'ennemi peut atteindre le joueur, vous pouvez ajouter une fonctionnalité lui permettant d'infliger des dégâts au joueur en cas de collision. Dans ce tutoriel, vous allez créer un ennemi qui s'autodétruit au contact du joueur. Vous allez donc ajouter une logique pour éliminer cet ennemi une fois qu'il a infligé des dégâts au joueur.
Pour vérifier si l'ennemi est entré en collision avec le joueur, procédez comme suit :
Dans le panneau Composants, faites un clic droit sur le composant de capsule (CollisionCylinder), accédez à Ajouter l'événement et sélectionnez Ajouter OnComponentHit.
Un nouveau nœud d'événement est créé dans le graphique d'événements ; il s'exécute lorsque le composant de capsule entre en collision avec un objet.
Faites glisser la broche du nœud On Composant Hit et créez un nœud Branch.
Reliez la broche Condition à la broche Autre acteur du nœud On Component Hit, ce qui vous invite à créer un nouveau nœud.
Créez un nœud Equal. Faites glisser la broche Sélectionner une ressource du nœud Equal et ajoutez une référence à la variable Réf. de joueur.
Cette logique déclenche un événement lorsque le composant de capsule de l'ennemi entre en collision avec un objet dans le jeu. L'événement vérifie si le composant de capsule est entré en collision avec le personnage joueur.
Pour n'infliger des dégâts au joueur qu'une seule fois et supprimer l'ennemi, procédez comme suit :
Dans la liste des variables, créez une nouvelle variable nommée Éliminé et définissez son type sur Booléen. Vous utilisez cette variable lorsque l'ennemi est vaincu et doit être éliminé du jeu.
Pour vous assurer qu'il n'inflige de dégâts qu'une seule fois au joueur, faites glisser la broche True du nœud Branch et créez un nœud Do Once.
Depuis la broche Completed du nœud Do Once, créez un nœud Apply Damage. Faites glisser la broche Damaged Actor et reliez une référence à la variable PlayerRef. Il s'agit de l'acteur qui doit subir les dégâts.
Faites un clic droit sur la broche Base Damage et sélectionnez Promouvoir vers la variable.
Dans la liste des variables, cliquez sur l'icône d'œil de la propriété Dégâts de base pour la rendre modifiable et définissez sa catégorie sur Configuration. Compilez le blueprint et définissez la valeur par défaut sur
25.Faites glisser la variable Eliminated de la liste des variables dans le graphique d'événements et sélectionnez Définir. Dans le nœud, cliquez sur la case à cocher pour définir Eliminated sur true.
Reliez la broche Exec du nœud Apply Damage au nœud Set Eliminated.
Faites glisser la broche Exec du nœud Set Eliminated et créez un nœud Delay. Définissez l'option Durée sur
2,0.Faites glisser la broche Exec du nœud Delay et créez un nœud Destroy Actor. La propriété Cible doit être définie sur Soi-même par défaut.
Lorsque l'ennemi entre en collision avec le joueur, il lui inflige des dégâts, puis il s'autodétruit après un délai de 2 secondes.
L'ennemi peut maintenant courir vers le joueur, lui infliger des dégâts, puis s'autodétruire lorsqu'il entre en collision avec lui. Néanmoins, ni la distance ni les obstacles entre le joueur et l'ennemi ne sont pris en compte. L'ennemi poursuit toujours le joueur, quelle que soit la distance ou la ligne de mire.
La logique BP_Enemy de On Composant Hit doit ressembler à ceci :
Pour copier l'extrait de blueprint ci-dessous dans votre graphique d'événements BP_Enemy, assurez-vous que les noms des variables correspondent à ceux de l'exemple de projet.
Ajouter une logique de distance et d'obstacle
Ajoutez ensuite une distance de détection maximale afin que l'ennemi ne puisse détecter le joueur que lorsqu'il est suffisamment proche de lui. Enfin, délimitez précisément la ligne de mire de l'ennemi afin qu'il ne puisse pas voir le joueur à travers les murs.
Pour ce faire, vous devez commencer par créer une fonction dans votre bibliothèque de blueprints qui effectue un tracé de ligne entre l'ennemi et le joueur.
Calculer la ligne de mire et la distance avec un tracé de ligne
Le tracé de ligne (ou ray-casting) est une pratique courante dans le développement de jeux. Un tracé de ligne trace une ligne invisible à partir d'un point du monde (p. ex., un acteur source) afin de déterminer l'objet que la ligne touche. Il est fréquemment utilisé pour détecter des objets ou des surfaces à l'exécution afin de déclencher une logique en fonction du résultat du tracé.
Dans ce tutoriel, vous allez projeter un tracé de ligne à partir du personnage ennemi afin de détecter le moment où le personnage joueur se trouve dans la ligne de mire de l'ennemi.
Pour en savoir plus sur les tracés de ligne, consultez la documentation Traces with Raycasts.
Pour configurer une fonction qui utilise un tracé de ligne en vue de détecter le joueur, procédez comme suit :
Dans le navigateur de contenu, accédez à votre dossier Core et ouvrez la bibliothèque de blueprints
BPL_FPGame.Ajoutez une nouvelle fonction nommée
fnBPLFindPlayer.Dans le panneau Détails de la nouvelle fonction, accédez à la section Entrées, puis cliquez sur Ajouter (+) afin de créer les entrées suivantes :
Référence de joueur (référence d'objet de pion)
Emplacement de départ (vecteur)
Distance de détection max. (Float)
Débogage (Booléen)
Après avoir ajouté ces entrées, le nœud d'entrée de fonction fnBPLFindPlayer possède désormais des broches correspondantes pour chacune des variables.
Dans le panneau Détails de la fonction, accédez à la section Sorties, puis cliquez sur Ajouter (+) pour créer une valeur de sortie de type booléen appelée Trouvé.
Après avoir ajouté la sortie Trouvé, un nouveau nœud de retour apparaît dans votre graphique avec la broche Found.
Dans le panneau My Blueprint, accédez à la section Variables locales, puis cliquez sur Ajouter (+) pour créer une variable locale nommée PlayerFound de type booléen. Assurez-vous que sa valeur par défaut est définie sur false.
La référence de joueur est essentielle pour que la fonction s'exécute correctement. Lorsque la fonction démarre, vérifiez que la référence est valide pour éviter les erreurs.
Pour vérifier si une entrée est valide, procédez comme suit :
Supprimez le lien entre le nœud d'entrée et le nœud de retour en maintenant l'appui sur la touche Alt et en cliquant soit sur le lien soit sur la broche Exec de l'un ou l'autre des nœuds.
Après le nœud d'entrée de fonction, créez et reliez un nœud Is Valid.
Assurez-vous de créer un nœud Is Valid représenté par une icône de point d'interrogation (?) en bas de la liste des actions de nœud.
Reliez la broche Player Reference du nœud d'entrée à la broche Input Object du nœud Is Valid.
Reliez la broche d'exécution Is Not Valid au nœud de retour.
Pour la valeur de retour Trouvé, reliez une référence à la variable PlayerFound. Cela permet de quitter la fonction et de renvoyer PlayerFound=False dans le graphique d'événements de l'ennemi.
Si le joueur est valide, la fonction doit exécuter l'objet de tracé de ligne, puis renvoyer PlayerFound.
Pour configurer le tracé de ligne, procédez comme suit :
À partir de la broche d'exécution Is Valid, ajoutez un nœud Sequence pour organiser votre logique.
Faites glisser la broche Then 0 du nœud Sequence et ajoutez un nœud Line Trace By Channel.
Line Trace By Channel détecte les objets sur un canal de collision spécifique. Pour afficher les paramètres des canaux de collision d'un blueprint, sélectionnez le composant de collision du blueprint, puis accédez aux propriétés Collision > Préréglages de collision dans le panneau Détails. La section Réponses du tracé comporte les canaux Visibilité et Caméra.
Faites glisser la broche Start Location du nœud d'entrée de fonction et reliez-la à la broche Start du nœud Line Trace By Channel. Vous définissez ainsi l'emplacement du personnage ennemi comme point de départ du tracé de ligne.
Pour maintenir votre graphique ordonné, créez un nœud Get Player Reference. L'icône F dans le coin supérieur droit du nœud indique qu'il s'agit d'une entrée de fonction. Vous pouvez ajouter des références à ces entrées comme pour n'importe quelle autre variable.
Faites glisser la broche Player Reference vers un espace vide du graphique. La liste des actions de nœud s'ouvre. Dans la liste, recherchez et créez un nœud Get Actor Location.
Reliez sa valeur de retour à la broche End du nœud Line Trace. Le tracé de ligne se termine ainsi à l'emplacement où se trouve le joueur.
Sur le nœud Line Trace By Channel, définissez la propriété Canal de tracé sur Caméra en utilisant le menu déroulant.
Maintenant que vous avez défini les points de départ et d'arrivée du tracé de ligne, déterminez ce qui se passe lorsque le tracé rencontre un obstacle.
Pour vérifier si un tracé de ligne entre en collision avec le joueur, procédez comme suit :
Faites glisser la broche Out Hit du tracé de ligne et ajoutez un nœud Break Hit Result. Lorsqu'un tracé de ligne entre en collision avec un objet, de nombreuses informations sont collectées. Dans la mesure où seules certaines valeurs spécifiques sont nécessaires, vous devez disposer d'un nœud Break Hit Result pour diviser les données en composants individuels des données renvoyées.
Dans le nœud Break Hit Result, cliquez sur la flèche dans la partie inférieure pour afficher des options supplémentaires.
Vous voulez savoir si le joueur se trouve dans la ligne de mire et à une certaine distance de l'ennemi ; vous utiliserez donc la broche Hit Actor pour vérifier la présence du joueur, puis Trace Start et Trace End pour mesurer la distance jusqu'à l'objet touché.
Faites glisser la broche Hit Actor et ajoutez un nœud d'opérateur Equal. Pour l'entrée inférieure, reliez une référence à l'entrée de fonction Référence de joueur.
Pour référencer les valeurs d'entrée de fonction, vous pouvez ajouter un nœud Get, comme pour les autres variables.
Créez un nœud Distance (Vector). Reliez V1 à Trace Start, puis V2 à Trace End.
Un vecteur est un ensemble de valeurs X, Y et Z qui représentent la position d'un objet ou d'un point dans un espace 3D. Le nœud Distance calcule la distance entre deux de ces points, ce qui donne une valeur float.
Faites glisser la valeur de retour du nœud Distance et ajoutez un nœud Less (<). Pour l'entrée inférieure, reliez une référence à l'entrée de fonction Distance de détection max.
Créez un nœud AND (Boolean).
Reliez les broches de sortie booléennes des nœuds Equals (==) et Less (<) aux broches de sortie du nœud AND.
Avec cette logique, le nœud AND renvoie la valeur true si le tracé de ligne entre en collision avec un acteur égal à Référence de joueur, et si la distance entre le début du tracé (l'ennemi) et la fin (l'objet touché) est inférieure à la distance de détection maximale.
Pour utiliser le résultat du tracé afin de définir et de renvoyer la valeur de PlayerFound, procédez comme suit :
Faites glisser la broche de sortie du nœud AND et ajoutez un nœud Branch.
Reliez sa broche Exec pour qu'elle s'exécute après Line Trace By Channel.
Depuis la broche d'exécution True du nœud Branch, créez un nœud de variable Set pour définir la variable locale PlayerFound sur true.
Depuis la broche False du nœud Branch, créez un nœud Set PlayerFound. Conservez la valeur false.
Vous avez terminé avec la logique de tracé de ligne. Revenez au nœud Sequence et reliez sa broche Then 1 au nœud de retour pour quitter la fonction et envoyer le résultat PlayerFound au blueprint de l'ennemi.
Ajouter une option de débogage de tracé de ligne
Vous souhaitez pouvoir facilement activer ou désactiver un visuel de débogage du tracé de ligne dans l'éditeur de niveau. Cependant, le nœud Line Trace ne vous permet de choisir qu'une seule option dans la liste Type de débogage de dessin. Vous pouvez utiliser un nœud Select pour pouvoir modifier le type de débogage dans l'éditeur de niveau.
Pour configurer une option de débogage personnalisable pour le tracé de ligne, procédez comme suit :
Faites glisser la broche Draw Debug Type du nœud Line Trace By Channel et créez un nœud Select.
Reliez la broche Index du nœud Select à une référence à l'entrée Débogage de la fonction.
Étant donné que l'index du nœud Select est un caractère générique, lorsque vous connectez la valeur de type booléen Débogage, les options deviennent False et True.
Définissez l'option False sur Aucun. Définissez l'option Pour une durée sur True.
En bas du nœud Line Trace By Channel, cliquez sur la flèche pour afficher des options supplémentaires. Définissez l'option Temps de dessin sur
0,1seconde.Enregistrez et compilez votre bibliothèque de fonctions de blueprint.
Cette logique utilise la variable Débogage pour déterminer si le dessin de débogage du tracé de ligne est actif ou non :
Lorsque la variable Débogage est définie sur false, l'option Type de débogage de dessin est définie sur Aucun, ce qui indique qu'aucun dessin de débogage n'est rendu.
Lorsque l'option Débogage est définie sur true, le nœud Select modifie l'option Type de débogage de dessin pour la définir sur Pour une durée afin d'effectuer le rendu du tracé de ligne à l'exécution pendant une durée définie.
La fonction fnBPLFindPlayer terminée doit ressembler à ce qui suit :
Si vous copiez cet extrait de blueprint dans votre projet, vous devez relier la broche Exec et la broche Player Reference du nœud d'entrée de fonction à la broche Exec et la broche Input Object du nœud Is Valid. Pour copier l'extrait correctement, assurez-vous que les noms des entrées de fonction correspondent à ceux de l'exemple de projet.
Logique de mise à jour du déplacement vers le joueur
Maintenant que vous pouvez appeler une fonction qui recherche le joueur en prenant en compte la distance et la ligne de mire, ajoutez une logique à l'ennemi pour qu'il recherche et poursuive le joueur uniquement lorsqu'il le voit, ou lorsque le tracé de ligne détecte correctement le joueur.
Pour que l'ennemi poursuive le joueur après l'avoir trouvé, procédez comme suit :
Revenez au blueprint
BP_Enemy. Dans le graphique d'événements, recherchez le nœud Event Tick fourni.Faites glisser la broche Exec du nœud Event Tick et créez un nœud Branch.
L'événement Sur tick s'exécute à chaque image au cours du jeu. Utilisez-le pour que l'ennemi vérifie constamment la position du joueur et détermine s'il doit se lancer à sa poursuite.
Faites glisser la broche Condition du nœud Branch et créez un nœud NOT Boolean, qui renvoie l'inverse de la valeur d'un booléen.
Dans ce cas, étant donné que vous souhaitez ignorer la variable Eliminated, faites glisser la broche d'entrée du nœud NOT et recherchez Get Eliminated.
Cela vérifie si l'ennemi n'est pas éliminé avant de passer à la broche True du nœud Branch.
Faites glisser la broche True du nœud Branch et créez un nœud FnBPLFindPlayer. Ce nœud effectue un tracé de ligne pour rechercher le joueur dans le monde et vérifie la distance qui sépare l'ennemi du joueur.
Sur le nœud Fn BPLFind Player, effectuez les connexions suivantes en utilisant ses broches :
Player Reference : connectez une référence à la variable PlayerRef.
Start Location : créez un nœud Get Actor Location en définissant la propriété Cible sur soi. Vous attribuez ainsi l'emplacement de départ du tracé de ligne à la position de l'ennemi dans le monde.
Max Detection Distance : faites un clic droit sur la broche et sélectionnez Promouvoir vers la variable. Cliquez sur l'icône d'œil pour rendre cette variable modifiable, puis définissez sa catégorie sur Configuration. Compilez et définissez sa valeur par défaut sur
20 000(200 mètres). Plus la valeur est faible, plus le joueur doit se trouver près des ennemis pour qu'ils le détectent.Debug : sélectionnez Promouvoir vers la variable et nommez-la
DebugDetection. Rendez également cette variable modifiable et faites-la apparaître dans la catégorie Configuration.
Si le tracé de ligne détecte le joueur, définissez la vitesse de déplacement maximale de l'ennemi sur la valeur souhaitée, en déplaçant l'ennemi vers le joueur. Dans le cas contraire, définissez la vitesse sur 0 pour que l'ennemi ne puisse pas s'approcher du joueur.
Pour que l'ennemi se déplace lors de la détection du joueur et ne bouge pas dans le cas contraire, procédez comme suit :
Dans le nœud FnBPLFindPlayer, faites un clic droit sur la broche Found et cliquez sur Promouvoir vers la variable. Un nœud Set est donc automatiquement connecté pour cette nouvelle variable. Vous pouvez maintenant utiliser ce résultat Trouvé ailleurs dans le graphique.
Après le nœud Set, connectez un nœud Branch. Faites glisser la broche Condition du nœud Branch vers la broche de sortie du nœud Set Found.
Dans le panneau Composants, faites glisser Déplacement du personnage (CharMoveComp) dans le graphique d'événements. Faites glisser sa broche et créez un nœud Set Max Walk Speed.
Faites glisser la broche True du nœud Branch et reliez-la au nœud Set Max Walk Speed.
Pour la broche Max Walk Speed du nœud Set, connectez une référence à la variable Vitesse maximale.
Après le nœud Set, reliez un nœud MoveToPlayer pour appeler cet événement et faire en sorte que l'ennemi ne se déplace que s'il a trouvé le joueur.
Dupliquez les nœuds Set Max Walk Speed et Character Movement. Reliez la broche False du nœud Branch au nouveau nœud Set.
Dans le deuxième nœud Set Max Walk Speed, veillez à ce que la valeur de vitesse de marche soit définie sur 0. De cette façon, l'ennemi cesse de se déplacer sans annuler sa tâche AI MoveTo et sans avoir besoin de la relancer.
Maintenant que l'ennemi recherche le joueur à chaque image, supprimez le nœud Move to Player que vous avez ajouté à la fin de la logique Événement BeginPlay. Ce nœud était utile pour tester un ennemi partiellement terminé, mais vous n'en avez plus besoin.
Accédez à votre logique d'événement MoveToPlayer. Désormais, vous souhaitez que l'ennemi s'exécute uniquement si le joueur a été détecté :
Faites glisser la broche du nœud MoveToPlayer et créez un nœud Branch.
Pour la broche Condition du nœud Branch, ajoutez une référence à la variable Trouvé.
Dorénavant, si le joueur se trouve à la distance définie de l'ennemi et qu'il n'y a pas d'obstacle entre eux, la vitesse de déplacement de l'ennemi est définie sur la variable MaxSpeed et il exécute la logique MoveToPlayer. Si l'une de ces conditions n'est pas remplie, la vitesse de déplacement de l'ennemi est définie sur 0, ce qui empêche l'ennemi de se déplacer vers le joueur.
La liste finale des variables de BP_Enem doit ressembler à ce qui suit :
Pour copier les extraits de blueprint ci-dessous dans votre graphique d'événements BP_Enemy, assurez-vous que les noms de variables correspondent à ceux de l'exemple de projet.
La logique finale Événement BeginPlay du blueprint BP_Enemy doit ressembler à ce qui suit :
La logique finale MoveToPlayer du blueprint BP_Enemy doit ressembler à ceci :
La logique finale Event Tick du blueprint BP_Enemy doit ressembler à ce qui suit :
Autoriser les ennemis à subir des dégâts
Avant de finaliser ce blueprint, vous devez vous assurer que l'ennemi peut lui aussi subir des dégâts. Si vous poursuivez le développement de votre jeu au-delà de cette série de tutoriels, vous souhaiterez peut-être mettre en place des pièges capables d'infliger des dégâts au joueur ou de lui donner la possibilité de s'équiper d'un objet lui permettant d'infliger des dégâts aux ennemis et de les éliminer.
Pour infliger des dégâts aux ennemis, procédez comme suit :
Faites un clic droit n'importe où dans le graphique d'événements et créez un nœud Event AnyDamage.
Faites glisser la broche Exec de l'événement AnyDamage et créez un nœud Set CurrentHP.
Pour soustraire les dégâts infligés des points de vie actuels, faites glisser la broche de la propriété PV actuels et créez un nœud Subtract.
Faites glisser la broche supérieure du nœud Subtract et créez un nœud Get Current HP.
Reliez la broche inférieure du nœud Subtract à la propriété Dégâts du nœud Event AnyDamage.
Lorsqu'un acteur subit des dégâts, la valeur de la variable PV actuels est définie, les dégâts sont soustraits des points de vie, et la valeur de la propriété PV actuels est mise à jour.
Vérifiez ensuite si les PV actuels sont inférieurs ou égaux à 0, ce qui devrait éliminer l'ennemi.
Pour supprimer l'ennemi lorsque ses points de vie sont à 0, procédez comme suit :
Faites glisser la broche du nœud Set et créez un nouveau nœud Branch.
Faites glisser la broche Condition du nœud Branchet créez un nœud Less Equal (<=).
Reliez la broche de sortie du nœud Set Current HP à la broche d'entrée supérieure du nœud Less Equal. Veillez à ce que la broche inférieure soit définie sur 0.
Faites glisser la broche True du nœud Branch et créez un nœud Do Once.
Faites glisser sa broche Completed et créez un nœud Set Eliminated. Dans le nœud Set, définissez la propriété Éliminé sur true.
Après le nœud Set, reliez un nœud Delay en définissant la propriété Durée sur
2.Faites glisser la broche Completed du nœud Delay et créez un nœud Destroy Actor en définissant la propriété Cible sur Soi.
Enregistrez et compilez le blueprint.
La logique Événement AnyDamage du blueprint BP_Enemy doit ressembler à ce qui suit :
Tester le personnage ennemi terminé
Si vous jouez maintenant au jeu, l'ennemi risque de ne pas bouger selon la distance qui le sépare du joueur. Lorsque vous vous rapprochez de l'ennemi, il doit commencer à poursuivre le joueur.
Essayez de placer un obstacle. Quittez le mode de jeu et ajoutez un cube ou un mur de blocage au milieu de la zone du maillage de navigation en cliquant sur le bouton Créer dans la barre d'outils principale et en sélectionnant Formes > Cube. Cet obstacle vient obstruer le maillage de navigation.
Si le joueur commence derrière cet obstacle, l'ennemi ne peut pas le poursuivre, car le cube bloque le tracé de ligne ; l'ennemi ne parvient donc pas à trouver le joueur. Si le joueur contourne le cube et que l'ennemi a une vue directe sur le joueur, il commence à le poursuivre. Une fois que l'ennemi lance son action IA MoveTo, il continue de poursuivre le joueur même si celui-ci se cache derrière un obstacle.
Si vous souhaitez donner la possibilité à un ennemi de voir à travers un obstacle et de détecter le joueur, sélectionnez l'objet du niveau et accédez à Collision > Préréglages de collision dans le panneau Détails. Définissez le préréglage sur Personnalisé et activez l'option Ignorer dans le canal Caméra. Pour qu'un objet bloque le tracé de ligne, rétablissez le préréglage par défaut.
Positionner les ennemis dans votre projet
Dans notre exemple de niveau, nous avons placé plusieurs ennemis dans le couloir 3 et la pièce 3. Le premier ennemi se trouve seul dans le couloir 3 afin de permettre au joueur de vivre une rencontre initiale simple et de l'aider à comprendre le comportement et les aptitudes de ce personnage. Après la rencontre avec l'ennemi unique dans le couloir, nous avons placé deux personnages ennemis supplémentaires dans la pièce 3 afin d'augmenter le niveau de difficulté pour le joueur.
Vous pouvez varier le nombre et les types d'ennemis pour offrir différents niveaux de difficulté dans votre projet. Présenter progressivement aux joueurs de nouveaux ennemis et défis permet de créer une courbe de difficulté équilibrée que le joueur peut dominer au fil des parties. Une fois que le joueur a appris à se déplacer et à vaincre ses ennemis, proposez-lui un adversaire plus redoutable afin de le mettre au défi et de rendre le jeu plus stimulant.
Suivant
Dans le prochain module, vous apprendrez à ajouter une mécanique de sprint à l'ensemble de mouvements du joueur. Le joueur pourra ainsi se déplacer dans des zones familières du niveau et disposer d'un outil pour éviter les ennemis que vous avez ajoutés au projet.