Tâches de PNJ
Dans GTA V, tu ne pilotes jamais directement les membres d'un personnage. Tu ne calcules pas les rotations d'os ni l'avancement pas à pas chaque milliseconde. À la place, tu transmets des ordres de haut niveau au sous-système d'intelligence artificielle du moteur : les Tasks (tâches).
Le fonctionnement de la file de tâches
Chaque Ped expose une propriété Task qui donne accès à des centaines de comportements natifs :
// Faire marcher un PNJ vers des coordonnées précises
ped.Task.GoTo(positionCible);
// Faire fuir le PNJ loin du joueur
ped.Task.FleeFrom(player);
// Mettre le PNJ en faction avec une animation d'attente
ped.Task.StartScenarioInPlace("WORLD_HUMAN_GUARD_STAND", 0, false);
Dès qu'une tâche est assignée, le planificateur natif prend le relais. Il gère la recherche de chemin autour des obstacles, les esquives, la synchronisation des pas et la physique jusqu'à ce que la tâche soit accomplie ou interrompue.
Interrompre une tâche : le motif ClearAll
Si un PNJ est en plein déplacement ou en alerte, lui assigner un nouvel ordre ne prend pas toujours effet immédiatement si les anciens ordres n'ont pas été annulés :
// Annuler toutes les tâches en cours ou en attente
ped.Task.ClearAll();
// Assigner le nouvel ordre
ped.Task.FleeFrom(player);
Si tu souhaites couper net toute animation en cours sans transition douce, ClearAllImmediately() force une réinitialisation instantanée.
Jouer des animations et des scénarios
Jouer des animations personnalisées demande de charger le dictionnaire d'animation (AnimationDictionary), exactement comme un modèle 3D :
string dict = "amb@world_human_cheering@male_a";
string anim = "base";
GTA.Native.Function.Call(GTA.Native.Hash.REQUEST_ANIM_DICT, dict);
ped.Task.PlayAnimation(dict, anim, 8f, -1, AnimationFlags.Loop);
Pour les gestes d'ambiance simples, les scénarios prédéfinis comme WORLD_HUMAN_GUARD_STAND ou WORLD_HUMAN_SMOKING sont plus pratiques car le moteur gère le chargement de l'animation de manière transparente.
Enchaînement de tâches et pause coopérative (yielding)
Quand tu veux qu'un PNJ enchaîne des actions séquentielles (marcher vers un repère, attendre deux secondes, faire un geste), tu as deux approches :
- TaskSequence : Un conteneur natif qui empile les tâches dans l'ordre.
- Machine à états avec yielding : Laisser
OnTicksuivre l'avancement d'une image à l'autre sans jamais bloquer le thread.
N'utilise jamais Thread.Sleep(). Si tu te trouves dans une boucle dédiée au sein d'une fibre, appelle Script.Yield() :
ped.Task.GoTo(position);
// Attente coopérative tant que le ped n'est pas arrivé
while (ped.Position.DistanceTo(position) > 1.5f)
{
Script.Yield();
}
ped.Task.StartScenarioInPlace("WORLD_HUMAN_CHEERING", 4000, false);
Dans la leçon suivante, nous étudions les tâches de combat : armer un acteur, assigner une cible et gérer la riposte.