Dans cette partie du tutoriel, vous allez créer un ennemi qui détecte et poursuit le joueur, et lui inflige des dégâts. L'ennemi pourra par ailleurs 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 l'environnement dans lequel l'IA peut naviguer. Le maillage de navigation définit les zones et emplacements spécifiques de la carte que les différents personnages à IA peuvent parcourir pendant le jeu.
Créer un ennemi
En plus des tâches que vous avez effectuées sur les blueprints dans les tutoriels précédents, vous allez cette fois-ci ajouter un objet pour représenter visuellement l'ennemi et lire une animation à l'aide d'un blueprint d'animation. Le blueprint d'animation est fourni dans les fichiers du projet. Vous ne pourrez donc pas le créer de toutes pièces, mais il est important d'apprendre à l'intégrer dans le blueprint du personnage ennemi.
Commencez par créer le blueprint d'ennemi. Procédez comme suit :
Accédez au navigateur de contenu, puis à Contenu > AdventureGame > 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 la classe de base Personnage.
Nommez cette classe BP_Enemy et ouvrez-la dans l'éditeur de blueprint en double-cliquant dessus.
Lorsque vous créez un blueprint, vous créez également une classe de blueprint, qui fait partie de la ressource de blueprint et définit la fonctionnalité d'un blueprint. Ainsi, lorsque vous ajoutez une fonctionnalité, vous modifiez la classe de blueprint. Dans cet exemple, vous créez une ressource de blueprints nommée BP_Enemy, qui utilise le même nom pour la classe de blueprint.
La classe de base peut être considérée comme un modèle doté de fonctionnalités prédéfinies, que votre nouvelle classe de blueprint peut utiliser. Dans ce cas, la classe de base Personnage dispose de fonctionnalités relatives aux personnages du jeu, comme le mouvement et la rotation de caméra pour le regard. En utilisant cette classe de base, vous pouvez utiliser les fonctionnalités prédéfinies sans la recréer.
Le blueprint de joueur, BP_AdventureCharacter, utilise également la classe Personnage, de sorte que les personnages joueurs et ennemis disposent des mêmes fonctionnalités de base, que vous pourrez réutiliser.
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. Il s'agit du composant qui possède ses propres fonctions et variables associées au mouvement, comme la vitesse de déplacement maximale, qui fait partie de la classe de base Personnage. Vous pouvez utiliser ce composant lorsque vous créez une fonctionnalité similaire pour les ennemis dans votre projet.
Ajouter un modèle 3D à l'ennemi
Commencez par ajouter un nouveau composant. Procédez comme suit :
Sélectionnez le composant Maillage squelettique et accédez au le panneau Détails situé le côté droit de la fenêtre. Recherchez la catégorie Maillage et cliquez sur le menu déroulant en regard de la ressource Maillage squelettique.
Dans la liste, recherchez le modèle SKM_Manny_Simple et sélectionnez-le. Le modèle Manny est ainsi assigné au blueprint.
Accédez ensuite à la catégorie Animation. Cliquez sur le menu déroulant en regard de la classe Anim, puis assignez le blueprint d'animation ABP_Unarmed. Dans ce contexte, ABP signifie "blueprint d'animation".
Modifiez le blueprint d'animation pour qu'il fonctionne correctement avec l'ennemi :
Dans la propriété de classe Anim 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_Unarmed pour 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 (>) au nœud Set Should Move en ignorant le contrôle d'accélération.
Enregistrez, compilez et fermez le blueprint.
Le personnage ennemi doit maintenant jouer une animation d'inactivité dans l'onglet Hublot.
Dans le hublot, une capsule entoure le personnage ennemi. Le composant Capsule est une représentation visuelle de la collision, que vous pouvez utiliser pour détecter les collisions avec d'autres objets comme les murs, le sol ou le personnage joueur.
Dans le hublot, vous constatez que le personnage est actuellement décalé par rapport au niveau du sol et n'est pas aligné avec le composant Capsule. Cela peut provoquer un désalignement pendant le jeu. Pour vous assurer que le maillage du personnage est correctement aligné avec le composant Capsule, déplacez le personnage vers le bas pour que ses pieds touchent la partie inférieure du composant.
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. Le maillage est ainsi placé en bas du collisionneur de capsule, ce qui empêche l'ennemi de flotter au-dessus du sol dans le jeu.
Assurez-vous que la face avant du personnage pointe dans la même direction que la flèche bleue, qui est visible dans le panneau Composants sous le nom Composant flèche (flèche). La flèche indique la direction dans laquelle se trouve la face avant du blueprint.
Le panneau Composants comporte le Composant flèche. Cette flèche est également représentée dans l'onglet Hublot sous la forme d'une flèche bleu clair.
Le composant flèche indique la direction dans laquelle le personnage doit être orienté pour se déplacer correctement dans toutes les directions. La direction de la flèche représente la direction "vers l'avant" du personnage.
En gardant cela à l'esprit, sélectionnez à nouveau le composant Maillage et faites pivoter le personnage sur l'axe Z via le panneau Détails, qui est le dernier champ sous Transformation. Vous pouvez le définir sur -90 pour le faire pivoter correctement.
| Orientation incorrecte | Orientation correcte |
|---|
Modifier le matériau du modèle 3D
Avant de passer à la création de la fonctionnalité, remplacez la couleur du modèle de l'ennemi par le rouge. Ce changement de couleur permet de le distinguer du joueur afin qu'il ressemble davantage à un ennemi (contrairement à la couleur blanche actuelle).
La section Matériaux du panneau Détails comporte deux éléments. MI_Manny_01_New est le matériau qui a une incidence sur plusieurs emplacements du modèle ennemi, comme les bras supérieurs, les jambes et la tête. MI_Manny_02_New est le matériau qui affecte les avant-bras et le torse.
En regard de la propriété Élément 0, cliquez sur le bouton Parcourir dans le navigateur de contenu, en forme de dossier avec une loupe. Le tiroir à contenu s'ouvre pour accéder au matériau sélectionné. Vous remarquerez que le deuxième matériau, MI_Manny_02_New, se trouve également dans le tiroir à contenu.
Faites un clic droit sur la ressource MI_Manny_01_New et choisissez Créer une instance de matériau. Une instance du matériau sélectionné est créée. Une instance de matériau hérite de tous les éléments du matériau parent, et vous pouvez remplacer les paramètres que vous souhaitez modifier. Par exemple, vous pouvez modifier la couleur, mais conserver tous les autres paramètres tels que la brillance du matériau.
Lors de la création d'une nouvelle instance de matériau, l'Unreal Engine lui attribue automatiquement une ressource en utilisant le préfixe IM. Ici, IM signifie instance de matériau. Vous pouvez créer une instance d'un matériau ou une instance de matériau pour poursuivre la ramification de matériaux existants.
Nommez la ressource d'instance de matériau MI_Enemy_01 et double-cliquez dessus pour l'ouvrir.
Dans le panneau Détails de droite, 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 rouge dans la fenêtre Pipette.
Dans le cadre de ce tutoriel, nous avons choisi une couleur rouge vif, que vous pouvez utiliser en collant le code F60E6EFF dans le champ sRVB hexadécimal en bas à droite de la pipette.
Cliquez sur le bouton Enregistrer dans le coin supérieur gauche de la fenêtre Matériau pour fermer la fenêtre.
Ensuite, accédez de nouveau au navigateur de contenu, faites un clic droit sur la ressource MI_Manny_02_New et cliquez sur Créer une instance de matériau.
Nommez cette instance de matériau MI_Enemy_02 et répétez les étapes précédentes sur ce matériau.
Après avoir répété cette procédure, vous devriez disposer de deux nouvelles instances de matériau, MI_Enemy_01 et MI_Enemy_02. Assurez-vous d'enregistrer vos deux ressources d'instance de matériau en utilisant le bouton Enregistrer dans les fenêtres de l'éditeur de matériau.
Attribuez ensuite ces matériaux au personnage ennemi. Ouvrez le blueprint BP_Enemy dans la fenêtre de Éditeur de blueprint, puis dans le panneau Détails, accédez à 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. Pou l'élément 1, sélectionnez le matériau MI_Enemy_02.
Votre personnage ennemi doit maintenant être rouge grâce aux nouvelles ressources d'instance de matériau.
Configurer l'ennemi au démarrage du jeu
L'ennemi étant prêt visuellement, vous devez maintenant créer la fonctionnalité de gameplay. Vous allez commencer par configurer les propriétés nécessaires pour l'ennemi quand il apparaît.
Procédez comme suit :
Dans la fenêtre de l'éditeur de blueprint BP_Enemy, accédez à l'onglet Graphique d'événements en regard de l'onglet Hublot. Par défaut, vous disposez de trois événements avec des commentaires sur le dessus : Event BeginPlay, Event ActorBeginOverlap et Event Tick. Sélectionnez l'événement ActorBeginOverlap et supprimez-le, car il n'est pas nécessaire pour ce tutoriel.
Tout d'abord, à l'aide du panneau Composants , faites glisser le composant Déplacement du personnage dans le graphique d'événements. Un nœud appelé Character Movement est ainsi créé. Faites glisser la broche de ce nœud et créez un nœud Set Max Walk Speed.
Faites un clic droit sur la broche verte Vitesse de marche max. du nœud Set et sélectionnez l'option Promouvoir vers la variable dans le menu contextuel. Une nouvelle variable est créée. Elle est visible dans le panneau My Blueprint, à gauche de l'éditeur de blueprint, sous la liste 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. Compilez le blueprint puis, dans le panneau Détails, définissez la valeur par défaut de l'option Vitesse max. sur 200.
Étant donné que cette variable est publique, vous pouvez définir sa valeur dans le niveau lorsque vous ajoutez un ennemi dans votre niveau. Si vous oubliez de modifier sa valeur et que la valeur par défaut est définie sur 0, l'ennemi ne peut pas se déplacer. En définissant la valeur par défaut sur 200, vous vous assurez que la vitesse de déplacement de l'ennemi est suffisante.
Dans la liste Variables, ajoutez une nouvelle variable appelée PV actuels de type Float.
Ajoutez une variable supplémentaire nommée Éliminé et définissez son type sur Booléen.
Faites glisser la variable PV actuels depuis la liste Variables dans le graphique d'événements et cliquez sur l'option Définir les PV actuels dans le menu contextuel. Faites glisser la broche d'exécution du nœud Set Max Speed et reliez-la à la broche d'exécution du nœud Set Current HP.
Sur le nœud Set Current HP, faites un clic droit sur la broche float de Current HP et cliquez sur Promouvoir vers la variable.
Renommez cette variable PV totaux. Définissez son type sur 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.
Il est important d'avoir deux variables de suivi de la valeur de PV de l'ennemi : la variable PV totaux permet de stocker le nombre de PV du personnage ennemi au début du jeu, et la variable PV actuels permet de suivre le nombre de PV dont dispose l'ennemi à tout moment, après avoir subi des dégâts de la part du joueur. Rendre publique la variable PV totaux vous permet de définir cette valeur pour chaque instance d'un blueprint de personnage ennemi dans votre niveau. Vous pouvez donc ajuster la difficulté de chaque ennemi, afin de rendre chaque ennemi plus difficile ou plus facile à vaincre.
É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. Dans la liste des variables, créez une nouvelle variable appelée Réf. de joueur et 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, connectez un nœud Set PlayerRef. Connectez un nœud Get Player Character pour la broche d'entrée Réf. de joueur. Vérifiez que la valeur Index de joueur de ce nœud est définie sur 0. Il s'agit de l'index par défaut du premier personnage joueur qui apparaît dans le niveau.
Connectez la logique que vous avez créée au nœud fonctionnel Event BeginPlay. Votre graphique d'événements doit ressembler à ceci :
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 ce faire, vous pouvez créer un événement personnalisé, similaire aux autres nœuds d'événement comme BeginPlay() mais personnalisé, que vous pouvez appeler de n'importe où dans le blueprint sans avoir à recréer la logique.
Pour créer un événement personnalisé, 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 nouvellement créé et saisissez AI MoveTo dans le champ de recherche. Sélectionnez le nœud IA MoveTo pour le créer.
Le nœud AI MoveTo est un événement que les pions avec un contrôleur IA peuvent utiliser pour se déplacer vers un emplacement spécifique. Dans ce cas, il permet de déplacer l'ennemi vers le joueur.
Sur le nœud IA MoveTo, faites glisser la broche Pion et saisissez Soi-même dans le champ de recherche. Sélectionnez l'option 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.
Ensuite, faites glisser la broche Acteur cible du nœud IA MoveTo et créez un nœud Get PlayerRef.
Dans ce cas, vous définissez le pion comme cet ennemi à l'aide du nœud Self qui permet de définir l'acteur qui va se déplacer. Définissez ensuite l'acteur cible, qui est la cible vers laquelle le pion se déplace, sur le personnage joueur dans le niveau.
Le nœud IA MoveTo dispose des événements À la réussite et À l'échec. Vous les utiliserez pour définir ce qui se passe si l'ennemi atteint le joueur ou s'il échoue.
Faites glisser la broche À la réussite et créez un nœud Delay.
Faites un clic droit sur la broche Durée du nœud Delay et sélectionnez Promouvoir vers la variable.
Nommez cette variable WaitAtDestination et définissez son type sur Float par défaut.
Compilez le blueprint, sélectionnez la variable WaitAtDestination et définissez la valeur par défaut sur 5. Cliquez sur l'icône d'œil correspondante pour la rendre modifiable et définissez sa catégorie sur Configuration.
Ensuite, dans le graphique d'événements, faites glisser la broche d'exécution du nœud Delay et créez un nœud Move To Player. L'événement Déplacer vers le joueur que vous avez créé est ainsi exécuté même si l'ennemi atteint le joueur, mais après un certain temps.
Ensuite, sur le nœud IA MoveTo, faites glisser la broche À l'échec et créez un nouveau nœud Delay. Faites glisser la broche Terminé de ce nœud et créez un nœud Move To Player. Laissez la valeur Durée du nœud Delay sur 0,2.
Vous vous assurez ainsi que l'ennemi continue de se déplacer même s'il n'atteint pas le joueur.
Revenez au nœud Event BeginPlay(). À la fin de cette séquence, après le nœud Set Player Ref, connectez 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.
Ce mouvement doit ressembler à ceci :
L'ensemble de votre blueprint doit maintenant ressembler à ceci :
Infliger des dégâts au joueur
Vous allez maintenant infliger des dégâts au joueur si l'ennemi l'atteint. Dans ce tutoriel, vous allez créer un ennemi qui s'autodétruit au contact du joueur. Vous allez donc ajouter une logique pour supprimer cet ennemi une fois qu'il a infligé des dégâts au joueur.
Procédez comme suit :
Dans le panneau Composants, sélectionnez le composant Capsule (CollisionCylinder).
Dans le panneau Détails, sous la section Événements, utilisez le bouton Ajouter (+) en regard de À l'impact du composant.
Un nouveau nœud d'événement est créé dans le graphique d'événements, qui s'exécute lorsque le composant (en l'occurrence le composant de capsule que vous avez sélectionné), heurte quelque chose.
Faites glisser la broche du nœud On Composant Hit et créez un nœud Branch. Faites glisser la broche Condition du nœud Branch jusqu'à la broche Autre acteur du nœud On Composant Hit ; vous êtes invité à créer un nouveau nœud.
Créez un nœud Equal qui vérifie que l'autre acteur détecté par le nœud On Composant Hit est l'acteur prévu, en l'occurrence le personnage joueur. Faites glisser la broche Sélectionner une ressource du nœud Equal et ajoutez une référence à la variable Réf. de joueur.
Un événement est ainsi déclenché lorsque le composant de capsule de l'ennemi heurte quelque chose dans le jeu. Cet événement vérifie que l'autre objet heurté par le composant de capsule est le personnage joueur. Il utilise cette information pour infliger des dégâts au joueur.
Dans ce tutoriel, vous allez créer un ennemi qui heurte le joueur une fois, puis s'autodétruit. 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 Terminé du nœud Do Once, créez un nœud Apply Damage. Faites glisser la broche Acteur endommagé et reliez une référence à la variable Réf. de joueur pour désigner cet acteur comme l'acteur auquel les dégâts sont infligés.
Ensuite, faites un clic droit sur la broche Dégâts de base 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 des dégâts sur 25.
Ensuite, faites glisser la variable Éliminé de la liste des variables dans le graphique d'événements et sélectionnez Définir.
Reliez la broche d'exécution du nœud Apply Damage au nœud Set Eliminated.
Activez la propriété Éliminé du nœud Set Eliminated sur true.
Faites glisser la broche d'exécution du nœud Set Eliminated et créez un nœud Delay. Définissez l'option Durée sur 2,0.
Ensuite, faites glisser la broche d'exécution 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 percute le joueur, il lui inflige des dégâts, puis il s'autodétruit après un délai de 2 secondes.
À ce stade, l'ennemi peut courir vers le joueur, lui infliger des dégâts et s'autodétruire s'il le percute. Cependant, il ne prend pas en compte la distance entre le joueur et l'ennemi et n'indique pas s'il existe des obstacles entre les deux, comme des murs. L'ennemi poursuit donc toujours le joueur, quoi qu'il arrive.
Ajouter une logique de distance et d'obstacle
Dans la section suivante de ce document, vous verrez comment définir une distance de détection maximale pour que l'ennemi ne détecte le joueur que lorsqu'il est suffisamment proche de lui. Enfin, vous finirez en créant une fonctionnalité qui empêche l'ennemi de voir le joueur à travers les murs. Le joueur doit donc se trouver dans la ligne de mire de l'ennemi pour être visible. 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
L'option Tracé de ligne est couramment utilisée dans le développement de jeux. Le tracé de ligne trace une ligne invisible qui part de l'acteur source, et qui croise et détecte d'autres objets et acteurs dans le jeu au moment de l'exécution. Vous pouvez ensuite utiliser les acteurs et les objets de jeu détectés par le tracé de ligne pour activer la logique de jeu. Dans ce tutoriel, nous allons vous montrer une configuration qui utilise un tracé de ligne du personnage ennemi, qui détecte 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 Tracés et ray casting.
Pour configurer une fonction qui utilise un tracé de ligne permettant de tester la distance et la ligne de mire par rapport au joueur, procédez comme suit :
Dans le navigateur de contenu, accédez à votre dossier Core et ouvrez la bibliothèque BPL_FPGame.
Ajoutez une fonction nommée fnBPLFindPlayer.
Dans le panneau Détails de la fonction, accédez à la section Entrées des propriétés et utilisez Ajouter (+) pour ajouter les types d'entrées suivants :
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, vous remarquez que le nœud fonctionnel fnBPLFindPlayer comporte des broches correspondantes pour chacune des variables.
Ensuite, dans le panneau Détails de la fonction, accédez à la section Sorties des propriétés et utilisez Ajouter (+) pour créer une variable de sortie booléenne Joueur détecté.
Après avoir ajouté la variable de sortie Joueur détecté, un nouveau nœud Return est créé dans votre graphique avec la variable de sortie Joueur détecté, connecté au nœud Entry.
Enfin, dans le panneau My Blueprint, accédez à la section Variables locales et utilisez Ajouter (+) pour créer une variable locale Joueur détecté (booléenne) et vous assurer que sa valeur par défaut est définie sur False.
Ensuite, vous devez ajouter une vérification d'erreur pour l'entrée du joueur. Pour ajouter cette vérification, procédez comme suit :
Supprimez le lien entre le nœud Entry et le nœud Return en maintenant la touche Alt enfoncée et en cliquant sur la broche d'exécution du nœud Entry ou du nœud Return.
Après le nœud d'entrée de fonction, créez et connectez un nœud Is Valid. Après avoir créé le nœud, faites glisser la broche Référence de joueur du nœud Entry et reliez-la à la broche Objet d'entrée du nœud Is Valid. Is Valid est une fonction de bibliothèque utilisable par tous les blueprints. Vous devez donc ajouter une condition pour les références de joueur non valides afin d'éviter les erreurs.
Reliez la broche d'exécution Is Not Valid au nœud Return. Pour la valeur Détecté, connectez 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.
Pour configurer le tracé de ligne, procédez comme suit :
Si le joueur est valide, la fonction doit exécuter l'objet de tracé de ligne, puis renvoyer PlayerFound. Ajoutez un nœud de séquence pour organiser votre logique.
Faites glisser la broche Then 0 du nœud de séquence et ajoutez un nœud Line Trace By Channel. Remarque : informations disponibles ici sur ce nœud. Que signifie "par canal" ? Toute documentation vers laquelle créer un lien.
Configurez le nœud Line Trace By Channel :
Faites glisser la broche Emplacement de départ du nœud Entry et reliez-la à la broche d'entrée Démarrer du nœud Line Trace By Channel. L'emplacement du personnage ennemi devient ainsi le point de départ du tracé de ligne.
Ensuite, faites glisser la broche Référence de joueur du nœud Entry n'importe où dans le graphique, afin d'ouvrir le menu contextuel du nœud Blueprint. Dans le menu contextuel, recherchez et créez un nœud Get Actor Location. Un nouveau nœud est ainsi créé, qui utilise la référence de joueur comme entrée de cible. 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.
Vous devez ensuite créer la fonctionnalité qui permet d'utiliser le résultat de collision du tracé de ligne pour vérifier le joueur et la distance d'impact, en procédant comme suit :
Faites glisser la broche Collision de sortie du tracé de ligne et ajoutez un nœud Break Hit Result. Lorsqu'un tracé de ligne heurte un objet, de nombreuses informations sont collectées. Dans le cadre de cette logique, il suffit d'utiliser quelques valeurs spécifiques. Un nœud Break Hit Result est donc nécessaire pour répartir les données dans les composants individuels des données renvoyées.
Dans le nœud Break Hit Result, cliquez sur la flèche inférieure pour afficher des options supplémentaires. Cette fonction a pour but de déterminer si le joueur se trouve dans la ligne de mire et à une certaine distance de l'ennemi. Vous devez donc utiliser l'acteur de collision pour contrôler le joueur, et le début du tracé et la fin du tracé pour mesurer la distance qui le sépare de l'objet touché
Faites glisser la broche Acteur de collision et ajoutez un nœud d'opérateur Equal. Pour l'entrée inférieure, connectez une référence à l'entrée de fonction Référence de joueur.
Créez un nœud Distance (Vector). Reliez V1 au début de trace, puis V2 à la fin de trace. Remarque : un vecteur est un ensemble de valeurs X, Y et Z qui représentent la position d'un point ou d'un objet dans un espace en 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, connectez une référence à l'entrée de fonction Distance de détection max.
Créez un nœud booléen AND, et reliez la sortie booléenne des nœuds Equal (==) et Less (<) aux broches d'entrée du nœud booléen AND. Avec cette logique, le nœud AND renvoie la valeur True si le tracé de ligne touche un acteur égal à la référence de joueur et si la distance entre le début du tracé (l'ennemi) et la fin du tracé (l'objet touché) est inférieure à la distance de détection max.
Faites glisser la broche de sortie du nœud AND, ajoutez un nœud Branch et configurez le nœud :
Connectez-le pour qu'il 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 Set Variable pour définir la variable locale PlayerFound sur True.
Depuis la broche d'exécution False du nœud Branch, créez un nœud Set Variable pour définir la variable locale PlayerFound sur False.
Vous avez terminé avec la logique du tracé de ligne. Revenez au nœud de séquence et reliez sa broche Then 1 au nœud Return pour quitter la fonction et envoyer le résultat PlayerFound au blueprint de l'ennemi.
Vous souhaitez pouvoir facilement activer ou désactiver un visuel de débogage du tracé de ligne dans l'éditeur de niveau. Toutefois, le nœud Line Trace ne vous permet de choisir qu'une seule option dans la liste Type de dessin de débogage. Vous pouvez utiliser un nœud Select pour connecter la variable booléenne modifiable Débogage à deux des options de la liste Type de dessin de débogage.
Pour configurer une option de débogage personnalisable pour le tracé de ligne, procédez comme suit :
Depuis la broche Type de dessin de débogage du nœud Line Trace By Channel, créez un nœud Select.
Connectez la broche Index du nœud Select à l'entrée de fonction Débogage du nœud Entry. L'index du nœud Select est un caractère générique. Ainsi, lorsque vous connectez la référence Débogage de type booléen, les options deviennent False et True.
Définissez False sur Aucun et True sur Pendant une durée.
Enregistrez et compilez votre fonction de blueprint.
Cette logique utilise la variable Débogage pour déterminer si le dessin de débogage Tracé de ligne est actif ou non. Lorsque la variable de débogage est définie sur False, le mode de débogage est défini sur Aucun, ce qui signifie qu'aucun dessin de débogage n'est rendu. Lorsque la variable de débogage est définie sur True, le nœud Select active le dessin de débogage Pendant une durée, qui effectue le rendu du tracé à l'exécution pour toute la durée pendant laquelle il est actif. Vous pouvez aussi utiliser d'autres options, comme Pour une image, qui ne dessine le tracé de ligne que pour une seule image, ou Persistant, qui laisse le dessin de débogage actif tant que le projet est en cours d'exécution. Dans cet exemple, l'option Pendant une durée est le moyen le plus utile pour dessiner le tracé de ligne lors du débogage.
Faire en sorte que les ennemis poursuivent 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 afin que celui-ci recherche et poursuive le joueur dès qu'il se trouve dans son champ de vision.
Procédez comme suit :
Dans le navigateur de contenu, sélectionnez Contenu > AdventureGame > Concepteur > Blueprints > Personnages et ouvrez BP_Enemy.
Dans le graphique d'événements, faites glisser la broche d'exécution du nœud Event Tick et créez un nœud Branch. Remarque : l'événement Au 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 booléen NOT qui renvoie l'inverse de la valeur d'un booléen. Dans ce cas, vous souhaitez annuler la variable Éliminé. Par conséquent, faites glisser la broche du nœud booléen NOT et recherchez Get Eliminated.
Cela permet de vérifier si l'ennemi n'est pas éliminé, auquel cas il continue à utiliser la broche True du nœud Branch.
Faites glisser la broche True du nœud Branch et créez un nœud FnBPLFind Player. Ce nœud effectue un tracé de ligne pour trouver le joueur dans le monde et vérifie la distance actuelle entre le joueur et l'ennemi.
Sur le nœud Fn BPLFind Player, effectuez les connexions suivantes en utilisant ses broches :
Référence de joueur : connectez une référence à la variable Réf. de joueur.
Emplacement de départ : créez un nœud Get Actor Location avec la propriété Cible définie sur Soi-même. L'emplacement de départ du tracé de ligne est ainsi assigné à la position de l'ennemi dans le monde.
Distance de détection max. : sélectionnez Promouvoir vers la variable, cliquez sur l'icône d'œil pour la rendre modifiable et définissez sa catégorie sur Configuration. Définissez sa valeur par défaut sur 20 000 (200 mètres) après la compilation du blueprint. Plus la valeur est faible, plus le joueur doit se trouver près des ennemis pour qu'ils le détectent.
Débogage : sélectionnez Promouvoir vers la variable et appelez-la Détection de débogage. Rendez également cette variable modifiable afin qu'elle apparaisse dans la catégorie Configuration.
Si le tracé de ligne détecte le joueur, vous pouvez définir 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.
Dans le nœud FnBPLFindPlayer, faites un clic droit sur la broche Détecté et convertissez-la en variable. Un nœud Set est automatiquement créé pour cette nouvelle variable. Connectez la broche d'exécution du nœud également. Vous pouvez maintenant utiliser ce résultat Détecté 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.
Dans le panneau Variables, faites glisser la variable Vitesse maximale dans le graphique d'événements, sélectionnez le nœud Get et reliez-le à la broche Vitesse de marche max. du nœud Set.
Ensuite, dupliquez les nœuds Set Max Walk Speed et Character Movement. Reliez la broche False du nœud Branch au nouveau nœud Set.
Définissez la propriété Vitesse de déplacement max. sur 0.
L'ennemi s'arrête ainsi de bouger sans annuler sa tâche AI MoveTo et sans avoir besoin de réexécuter la tâche.
Après le nœud Set, qui est connecté à la broche True du nœud Branch, 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 détecté le joueur.
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 d'événement BeginPlay. Ce nœud était utile pour tester un ennemi partiellement terminé, mais vous n'en avez plus besoin.
Accédez à la logique d'événement MoveToPlayer. Désormais, vous souhaitez que l'ennemi s'exécute uniquement si le joueur a été détecté :
Supprimez le lien entre le nœud d'événement et AI MoveTo. Connectez un nœud Branch entre ces deux nœuds en utilisant la broche True du nœud Branch.
Pour la broche Condition du nœud Branch, ajoutez une référence à la variable Détecté.
Si le joueur se trouve à la distance définie de l'ennemi et qu'il n'y a pas d'obstacle entre les deux, la vitesse de déplacement de l'ennemi est définie sur la variable Vitesse maximale et la logique MoveToPlayer est exécutée. 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.
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. 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 variable PV actuels dans le graphique d'événements, puis choisissez Définir les PV actuels.
Les dégâts infligés sont soustraits des PV actuels. Commencez par faire glisser la broche d'exécution du nœud Event AnyDamage et reliez-le au nœud Set.
Faites glisser la broche de la propriété PV actuels et créez un nœud Subtract.
Faites glisser la broche inférieure du nœud Subtract et reliez-la à la propriété Dégâts du nœud Event AnyDamage.
Ensuite, faites glisser la broche supérieure du nœud Subtract et créez un nœud Get Current HP.
Lorsque cet acteur subit des dégâts, il récupère la valeur de la variable PV actuels et y soustrait les dégâts, puis définit la valeur de PV actuels sur la nouvelle valeur.
Vérifiez maintenant si la variable PV actuels est inférieure ou égal à 0, ce qui devrait tuer l'ennemi.
Faites glisser la broche du nœud Set et créez un nouveau nœud Branch.
Faites glisser la broche Condition du nœud Branch et créez un nœud Less Equal (<=).
Faites glisser la broche supérieure et créez un nouveau nœud Get CurrentHP. Veillez à ce que la propriété de 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 Terminé 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 avec une valeur de durée de 2.
Enfin, faites glisser la broche Terminé du nœud Delay et créez un nœud Destroy Actor en définissant la propriété Cible sur Soi-même.
Veillez à enregistrer et à compiler le blueprint.
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 est l'abréviation de maillage de navigation ; vous pouvez l'utiliser pour définir 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.
Quittez l'éditeur de blueprint BP_Enemy et accédez à l'éditeur de niveau de l'Unreal Engine. Dans la barre d'outils principale, cliquez sur le bouton Ajouter, accédez à Volumes et créez un volume de limites de maillage de navigation. Un objet est ainsi créé, que vous pouvez utiliser pour assigner une zone navigable pour l'IA dans votre projet.
Si vous ne voyez pas les zones vertes, appuyez sur la touche P de votre clavier pour activer le mode de débogage. Ce mode permet de visualiser 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 du niveau.
À l'aide des outils de transformation, vous pouvez déplacer le maillage de navigation en changer son échelle (touches W et R de votre clavier) pour modifier les limites du maillage de navigation. Ajustez cette zone à votre convenance. Dans le cas qui nous occupe, après avoir sélectionné l'objet NavMeshBoundsVolume, changez l'échelle à 6, 7 et 1 dans les champs X, Y et Z du panneau Détails de la section Transformer.
Lorsque vous changez l'échelle du maillage de navigation et déplacez ce dernier, les zones vertes s'étendent en même temps que la taille de la boîte englobante, à moins que certains objets ne soient considérés comme des obstacles, par exemple les cubes.
Les parties coupées en rouge signifient que les IA dans votre jeu ne peuvent pas y accéder.
Conseil : si l'Unreal Editor inclut quoi que ce soit dans le maillage de navigation, sélectionnez cet objet de niveau de maillage et désactivez l'option Influence permanente sur la navigation dans le panneau Détails.
Si le message "Le maillage de navigation doit être reconstruit" s'affiche dans les informations de débogage, accédez à la barre de menus pour sélectionner Générer et sélectionnez Générer les chemins. Cette option permet de reconstruire votre maillage de navigation.
Ajouter l'ennemi au niveau
Après avoir créé et défini votre maillage de navigation pour vos personnages ennemis, vous pouvez ajouter ces derniers à votre niveau.
Ouvrez le navigateur de contenu et accédez à l'emplacement de votre blueprint d'ennemi. Faites glisser le blueprint d'ennemi dans le hublot du niveau et placez-le face au joueur. Assurez-vous que les deux se trouvent dans les limites du maillage de navigation, c'est-à-dire sur les zones vertes.
Sélectionnez l'acteur Ennemi dans le hublot de niveau ou dans les panneaux Organiseur. Dans le panneau Détails, les variables que vous avez ajoutées dans le blueprint apparaissent dans les sections de propriété Par défaut et Configuration. Vous pouvez modifier ces valeurs pour répondre aux besoins du projet ou activer la variable Déboguer la détection pour activer le dessin de débogage du tracé de ligne.
Si vous jouez maintenant au jeu, l'ennemi risque de ne pas bouger selon la distance qui le sépare du joueur. Si vous vous rapprochez de l'ennemi, il doit commencer à poursuivre le joueur.
Essayez d'utiliser un obstacle. Quittez le mode de jeu et ajoutez un cube au milieu de la zone verte en cliquant sur le bouton Ajouter dans la barre d'outils principale et en sélectionnant Formes > Cube. Le cube est donc automatiquement considéré comme un obstacle.
Si le joueur se trouve derrière ce cube, l'ennemi ne peut pas poursuivre le joueur, car le tracé de ligne est bloqué par le cube. L'ennemi est donc dans l'impossibilité de détecter le joueur. Si le joueur contourne le cube et que l'ennemi a une vue directe sur le joueur, il continue sa poursuite.
Si quelque chose ne fonctionne pas comme prévu, assurez-vous de revérifier que les variables que vous avez créées dans le blueprint disposent de valeurs correctes pour le BP_Enemy dans la scène. Si vous ne définissez pas les valeurs des options Distance maximale ou Distance de détection max., l'IA ennemie ne se déplace pas. Il en va de même si les valeurs sont trop faibles.
Concevoir des emplacements d'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 a été placé seul dans le couloir 3, afin d'offrir au joueur une première rencontre simple, lui permettant d'apprendre à connaître le personnage ennemi et ses aptitudes.
Après l'ennemi unique dans le couloir, nous avons placé deux personnages ennemis supplémentaires dans la pièce 3 afin d'introduire davantage de difficulté pour le joueur. Vous pouvez utiliser des variantes et le nombre d'ennemis de votre choix pour créer 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é plus équilibrée, que le joueur peut découvrir progressivement. Après avoir appris au joueur à se déplacer et à vaincre ses adversaires, créer une rencontre difficile avec un ennemi lui offre un défi qui peut s'avérer gratifiant.
Suivant
Dans le prochain module, vous apprendrez à créer une mécanique de sprint que le joueur peut utiliser pour se mouvoir et relever les défis en se déplaçant plus rapidement. Le joueur peut ainsi parcourir les espaces plus efficacement et disposer d'un outil pour éviter les ennemis que vous venez d'ajouter au projet.
Ajouter une mécanique de sprint au joueur
Utilisez les actions d'entrée pour ajouter une mécanique de sprint à l'ensemble des mouvements du personnage joueur.