Dernière mise à jour : 28/10/2019 à 13h35

Current Project : Who knows?

Index des tutoriaux

Bot Pathing

Les bots d'Unreal utilisent un système de jalons, afin de naviguer dans l'espace selon des chemins prédéfinis dans le but de se procurer des objets de plus en plus puissants, le tout en venant à bout des obstacles (objectifs, joueurs) qu'ils rencontrent sur leur chemin. La quasi-totalité des actors nécessaires à la mise en place de ces chemins se trouvent dans l'actor browser en tant que dérivés de la classe NavigationPoint :

NavigationPoint

Notez d'abord que les PlayerStarts et items (adrénalines, armes, santé, objectifs du jeu etc...) sont d'office considérés comme des jalons. Il n'est donc pas nécessaire d'ajouter un pathnode sur un Playerstart ou sur chaque Weaponbase pour que les bots sachent les utiliser: le jeu ajoute par défaut un InventorySpot invisible à ces endroits, qui permet aux bots de savoir utiliser ces chemins.

PathNode : La pathnode est le premier élément que vous devrez ajouter à votre map. Il s'agit du jalon de base. Réparti de manière homogène sur toute les surfaces navigables de votre map (tous les sols et tous les endroits où le bot est censé se déplacer), il permet au bot de se tracer des chemins vers un item. Ainsi, si votre bot se trouve d'un coté de votre map et qu'il désire atteindre un objet de l'autre coté, il va suivre les pathnode jusqu'à l'item, en empruntant le chemin le plus court, suivant diverses priorités. Le pathnode apparaît sous la forme d'une petite pomme marron. Afin que le moteur puisse relier plusieurs pathnodes, il ne doit pas y avoir plus de 1000 unités unreal entre deux pathnodes. En règle générale, un pathnode tout les 256 ou 512 unités est un bon choix car il permet de donner de nombreuses possibilités au bot sans recouvrir la map et ralentir excessivement le rebuild. La distance doit être plus courte dans les escaliers car les bots ont plus de difficultés à y naviguer.
Il n'est pas nécessaire d'aller chercher le pathnode dans l'actor browser, il se trouve, ainsi que le PlayerStart, dans le menu contextuel de base qui apparaît lors du clic droit:

Menu contextuel

La plupart du temps, il n'est pas utile d'aller tripoter les options du PathNode. Malgré tout, il existe plusieurs options qui peuvent être utiles dans des cas précis:

Propriétés du PathNode

Il existe deux dérivées du PathNode: RoadPathNode, qui permet de définir des chemins pour les véhicules terrestres, et FlyingPathNode qui permet de définir des routes aux véhicules aériens (et doivent être placés dans le ciel).

Les portes : Par défaut, lorsqu'une porte est placée dans votre niveau, le bot n'a aucun moyen de savoir s'il s'agit d'une porte, d'un pilier qui bouge, d'un piston, d'un objectif utilisé lors d'un évènement scripté etc... En conséquence, les portes bloquent les pathnodes et sont considérées par les bots comme des obstacles infranchissables. Même une fois ouvertes, les chemins ne passent pas par l'ouverture dégagée, car la position fermée bloque les chemins.

Dans les NavigationPoint, il existe un actor dédié à ce problème. Pour en avoir un aperçu, ouvrez la map DM-Flux2, et regardez une des portes.

DM-Flux2

Les portes de la map sont activées par des triggers et les bots savent les utiliser grâce à l'actor "DOOR" placé au niveau de la porte. Dans cette map, à cause de l'épaisseur du mover, les deux actors se trouvent DANS la porte :

Fonctionnement interne

Voila le fonctionnement théorique: Grâce à l'actor Door, le bot considère le mover comme ne gênant pas son passage et emprunte le chemin. Au passage, il pénètre dans le rayon du trigger qui soulève la porte et lui libère physiquement le passage. Notez d'ailleurs qu'un bot ignorera un Mover dans son chemin si bNoAIRelevance est paramétré sur "Vrai" dans les propriétés du Mover.

Si vous ouvrez les propriétés des trois objets (le mover, le door et le trigger), voici ce que vous verrez: Le trigger a pour event "DoorE", qui est aussi le tag du mover. Il a aussi pour tag TrigE. Dans le Door, onglet Door, vous noterez DoorTag: DoorE et DoorTrigger: TrigE. Il suffit en effet de mettre dans DoorTrigger le tag du trigger et dans DoorTag, le tag du mover, pour que les bots sachent utiliser la porte.
Il existe d'autres propriétés dans le Door qui permettent de modifier le fonctionnement:

Les Jumpers : Tout droit venus de Quake, les jumpers sont un des éléments les plus ludiques et les plus stratégiques du jeu. Le fonctionnement est simple: Vous, ou le bot, marchez dessus et hop, vous êtes expédié en express sur le point d'arrivée choisi.

Les exemples les plus spectaculaires se trouvent dans des maps comme DM-Plunge ou la (très très bonne) map BR-Skyline.

Jumper dans BR-Skyline

Contrairement à ce que je pensais quand j'ai commencé à mapper, et à ce que risquent de penser pas mal de gens, le jumper est un point immatériel de l'espace. L'effet de particules, le petit cercle de lumière et le socle spécial sont ajoutés par le mapper pour signaler le jumper, mais ils n'ont aucun lien avec.

Le jumper se trouve dans l'actor browser sous JumpPad. Il s'agit de l'actor nommé "UTJumpPad":

UTJumpPad

Pour utiliser un jumper, vous avez besoin de deux objets: le UTJumpPad, et un pathnode au point d'arrivée voulu:

Mise en place d'un Jumper

Si vous essayez de jouer la map et que vous marchez sur le jumper, vous serez envoyé à la vertical: le Jumper sait qu'il doit vous propulser mais il ne sait pas où. Pour lui donner un point d'arrivée, il suffit de mettre le nom du PathNode dans les ForcedPaths du Jumper (dans mon cas, PathNode0):

Jumper fonctionnel

Notez que si vous mettez plusieurs ForcedPaths à votre jumper, vous serez envoyé aléatoirement vers n'importe quel point d'arrivée. Le Jumper dosera lui-même la force et la vitesse à laquelle il doit envoyer un joueur pour atteindre la destination. Si pour une raison ou une autre, cela ne marche pas, vous pouvez influer légèrement sur la trajectoire. Par exemple, dans DM-Premaka, j'ai eu un problème, car une grosse décoration au plafond bloquait les joueurs qui se prenaient la tête dessus, et retombaient sans atteindre la destination du jumper.

Dans les propriétés, onglet JumpPad, vous pouvez définir un JumpZModifier. Par défaut, la valeur est "1", et c'est un multiplicateur. Si la trajectoire par défaut de votre JumpPad est deux fois trop basse, vous pouvez la doubler en mettant 2. Si elle est deux fois trop haute, vous pouvez la diminuer en entrant 0.5. Si vous voulez la diviser par 4, entrez 0.25, etc...
L'autre propriété est JumpSound: c'est le son qui sera joué lorsque quelqu'un passera sur le jumper. On met souvent un "BOING" quelconque, cela permet à l'adversaire de repérer le joueur qui passe par le jumper à l'oreille.

AssaultPath : Sans doute l'un des modificateurs d'AI les plus méconnus et pourtant le plus puissant, l'AssaultPath détermine des trajectoires d'assaut pour les équipes, dans les modes à objectifs (par exemple CTF, BR, AS, ONS, etc). À ce sujet, voir ce tutorial-ci.

ShootSpots : Les ShootSpots sont des points qui servent en mode Bombe de balle. Ils permettent de spécifier des points à partir desquels les bots tireront la balle vers le but, lorsqu'ils n'arrivent pas à passer au travers. Vous pouvez en placer plusieurs. Ils n'ont pas de propriété. Placez un BlueShootSpot dans la base bleue pour marquer un endroit où un bot rouge tirera vers le but bleu et vice-versa.

BlockedPath : Permet de bloquer un chemin. Utile à des fins de tests.

Utilisation des ascenceurs : Pour utiliser un ascenceur, vous avez besoin de quatre actors au moins: Le mover, un LiftCenter que vous placerez dessus, un LiftExit à chaque sortie.

LiftCenter : Il fonctionne un peu comme l'actor DOOR, mais pour les ascenceurs. Dans le LiftTag, mettez le tag du mover, et dans le LiftTrigger, le tag de l'éventuel trigger (sinon, laissez vide).

LiftExit : Cet actor marque la sortie de l'ascenceur et fait la jointure entre le réseau de navigation normal et le LiftCenter. Placez-en un à chaque sortie que le bot doit pouvoir utiliser.

Ascenceur dans DM-Atomnium

Dans l'onglet Lift-Exit, mettez le tag du mover dans Lift-Tag. Le champ SuggestedKeyFrame permet au bot de ne pas faire le sombre abruti en sautant d'en haut sur l'ascenseur, pour essayer d'arriver en bas: mettez y la keyframe à laquelle le mover doit être pour que le Lift-Exit soit utilisable. Pour le cas d'un simple ascenseur à deux Keys :

Ascenceur fonctionnel

Il est aussi possible d'utiliser les Lift-Exit et leur onglet LiftJump pour donner aux bots la possibilité de faire un lift jump. Placez simplement un Lift-Exit supplémentaire à l'endroit où le bot doit atterrir, et mettez en Suggested Keyframe la keyframe à partir de laquelle le bot doit sauter (en général la keyframe finale, celle où l'ascenseur est au sommet, dans mon cas la keyframe 1). Dans l'onglet LiftJump, mettez bLiftJumpExit à VRAI. Vous pouvez aussi interdire au bot de faire un double saut au sommet du lift-jump en mettant bNoDoubleJump à Vrai.

Ascenceur permettant le Lift-Jump

Note: Dans DM-Reconstruct, AngelMapper utilise les lift-exit et lift-center d'une manière assez originale :

Reconstruct

Ici, il n'y a pas d'ascenseur: Lorsque quelqu'un passe, un pont se construit au fur et à mesure. Le bot doit donc pouvoir savoir qu'il y a un passage, mais il n'y a pas de sens défini, alors on ne met pas de suggested keyframe. L'un des movers qui constituent le pont qui se construit au fur et à mesure a pour tag Bridge202, ce qui indique au bot qu'un mover va bien se mettre en place pour permettre le passage. L'intelligence artificielle ignore simplement les autres triggers et movers, la construction du pont se fait à son insu. Les bots utilisent ce système à la perfection.

JumpSpot: Actor assez polyvalent, il permet d'indiquer à l'intelligence artificielle où sauter et de quelle manière. Il se trouve sous JumpDest dans l'actor browser.

JumpSpot

Ses dérivés incluent les GameObjectives qui sont en effet des destinations pour les bots.

Le JumpSpot doit être placé à l'endroit où le bot doit arriver en exécutant un saut, c'est-à-dire par exemple au sommet d'une haute marche que le bot ne peu pas franchir en marchant normalement. Il indique aussi aux bots où envoyer leur balise de téléporteur. Le JumpSpot pose quelques difficultés à l'IA et ne doit donc pas être utilisé sans retenue quand ce n'est pas nécessaire. Pour qu'un bot utilise le JumpSpot comme point d'arrivée d'un saut ou d'une téléportation, il faut mettre son nom dans le ForcedPath des pathnodes qui doivent y conduire.

Options du JumpSpot

Ses options permettent de déterminer quel type de saut doit être utilisé par l'IA pour accéder à ce point.

Onglet JumpDest:

A noter que selon UnrealWiki, il y a un bug dans la propriété TranslocZOffest, elle fonctionne de manière assez étrange et risque même de ne pas marcher du tout.

Un Jumpspot ne doit être placé qu'au sommet des endroits à atteindre. Steve Polge précise que le spot ne doit être "en bas" que si la chute risque d'être mortelle au bot ou lui causerait trop de dommages, pour le forcer à utiliser un téléporteur.

Playerstart : Le Playerstart est le point de spawn des joueurs et des bots. On y touche rarement, mais voici tout de même ses options:

Le playerstart a deux sous-classes: le triggeredPlayerstart a pour seul différence d'avoir par défaut bEnabled à Faux. Il peut être déclenché par trigger, ce qui mettra bEnabled sur Vrai et le rendra actif. Très utilisé dans les mods Assaut et Onslaught. L'autre sous-classe, xFieldPlayerStart, ne semble pas être utilisée.

Un dernier Cas: Les échelles: Pour créer une échelle, il faut placer un ladderVolume près du mur, qui touche le sol et dépasse de l'arète supérieure d'au moins la hauteur d'un joueur, et orienter le volume vers le mur (avec la propriété walldir). Les LadderVolumes créent automatiquement des points de navigation spéciaux: les actors "Ladder" (équivalent du DOOR actor pour les échelles en fait).

Si un problème survient, désactivez bAutoPath dans les options du ladder volume et placez-les à la main au sommet et au pied de l'échelle. Notons que les bots sont intelligents: ils éviteront d'utiliser une échelle si quelqu'un est déjà en train de l'utiliser (si le volume contient déjà quelqu'un).

Sniper : pour une fois, nous n'utiliserons pas un actor de la classe NavigationPoint, mais une UnrealScriptedSequence.

UnrealScriptedSequence

Placez-la à un endroit où vous voulez que votre bot campe. Elle contient par défaut deux actions: Move_to_point, vide, et une action_waitfortimer, qui est par défaut réglée sur trois secondes (vous pouvez changer), et qui fera attendre le bot en regardant dans la direction vers laquelle pointe l'UnrealScriptedSequence. Des options sont disponibles pour faire un réglage plus fin:

Débuggage

L'AI est un truc assez difficile à tester parce que vous ne pouvez pas vraiment savoir si votre bot a raté son mouvement ou si il a changé d'avis pendant qu'il s'y préparait. Unreal a plusieurs outils pour tester vos réseaux:

Le premier est Tool=>Review path. Cette commande va tester vos chemins pour:

Par contre, cet outil considère souvent comme des erreurs des trucs parfaitement normaux, alors utilisez-le avec précaution.

Lancez votre map depuis l'éditeur. Vous pouvez ajouter quelques bots avec la commande ADD BOTS X, où X est le nombre de bots à faire apparaitre. Vous pouvez alors utiliser certaines commandes:

Si vous tapez seulement ReviewJumpSpots, le bot va exécuter les quatre modes de test les un à la suite des autres. D'abord, il tentera de les atteindre au téléporteur, puis une fois tous les JumpSpots testés, il recommencera avec des impact jumps, etc.

Ces tests sont intéressants car vous pouvez voir ce qui ne va pas : un test manqué vous montrera clairement, par exemple, que le bot n'arrive pas à lancer la balise de son téléporteur à cause d'une décoration trop proéminente, etc. De plus, le résultat de tous les essais sera marqué dans le log d'UT2004 (/System/UT2004.log). Pour chaque essai, une ligne apparaitra sous la forme "Test ModeDeSaut from NomDeLaMap.NavigationPointDeDépart to NomDeLaMap.NavigationPointd'Arrivée:

ScriptLog: Test translocation from CTF-Senate.JumpSpot55 to CTF-Senate.JumpSpot21

Ensuite il affichera dans l'idéal la ligne

ScriptLog: Success!

Sinon, il affichera quelque chose comme FAILED. Dans ce cas, regardez l'actor de départ et l'actor d'arrivée. Repérez ces actors dans l'éditeur, et essayer de voir pourquoi ça ne marche pas. Parfois, c'est simplement une erreur de paramétrage, parfois c'est plus complexe. La translocation semble particulièrement difficile parce que les bots gèrent mal la trajectoire de la balise par rapport aux humains.

Lien utile : La présentation des actors par Steve Polge.

2005-2022, by Hellkeeper.

Valid XHTML 1.1 CSS 2.1