Animations et props FiveM : drapeaux TaskPlayAnim, attacher à un os, supprimer
Jouez des animations et attachez des props dans FiveM Lua : RequestAnimDict, drapeaux TaskPlayAnim 1, 16, 32 et 49, ClearPedTasks, AttachEntityToEntity à un os, scénarios et nettoyage.
Vous voulez qu'un joueur boive un café, tienne un téléphone ou utilise un outil : une animation, souvent avec un prop à la main. Fait mal, l'animation ne fait rien, le prop flotte aux pieds du joueur ou reste dans le monde pour toujours. Ce guide montre la séquence fonctionnante et le nettoyage.
Charger, jouer, effacer
Une animation vit dans un dictionnaire. Le dictionnaire doit être chargé avant de jouer dedans :
local function playAnim(ped, dict, anim, flag, duration)
RequestAnimDict(dict)
while not HasAnimDictLoaded(dict) do
Wait(0)
end
TaskPlayAnim(ped, dict, anim, 8.0, -8.0, duration or -1, flag or 0, 0.0, false, false, false)
endSi HasAnimDictLoaded n'est jamais vrai, le nom du dictionnaire est mauvais et cette boucle se bloque, donc ajoutez un timeout quand le nom vient de la config. Avec ox_lib, une ligne remplace la boucle :
lib.requestAnimDict('mp_player_inteat@burger')TaskPlayAnim prend le ped, le dictionnaire, l'animation, le mélange entrant, le mélange sortant, la durée en ms (-1 = jusqu'à l'arrêt), le drapeau, et un taux de lecture. Libérez le dictionnaire quand vous en avez fini avec RemoveAnimDict(dict).
Les drapeaux d'animation
Le drapeau est un masque de bits, donc les valeurs s'additionnent. Ceux que vous utiliserez :
| Drapeau | Effet |
|---|---|
| 0 | Jouer une fois, le joueur ne peut pas bouger |
| 1 | Boucle |
| 16 | Haut du corps seulement, les jambes continuent de marcher |
| 32 | Le joueur garde le contrôle |
| 49 | 1 + 16 + 32 : boucle, haut du corps, contrôlable |
Pour une animation tenue à la main (téléphone, boisson, cigarette), 49 est le choix habituel : elle boucle, seul le haut du corps est animé, et le joueur peut toujours marcher. Pour une action ponctuelle où le joueur doit se tenir immobile, utilisez 0, ou 1 si elle doit boucler.
Arrêter l'animation
local ped = PlayerPedId()
ClearPedTasks(ped) -- stop and let the ped blend out
-- or, if it is stuck:
ClearPedTasksImmediately(ped) -- cut instantly, can look abrupt
StopAnimTask(ped, dict, anim, 1.0) -- stop only that animationUtilisez StopAnimTask quand plusieurs choses s'exécutent sur le ped, car ClearPedTasks annule aussi la marche ou le scénario dessous. ClearPedTasksImmediately corrige un ped bloqué mais l'extrait aussi des véhicules, donc gardez-le pour la récupération.
Un prop à la main
Un prop est un objet que vous créez et attachez à un os du ped. La séquence : charger le modèle, créer l'objet, l'attacher, jouer l'animation.
local prop
local function attachProp(ped, model, bone, x, y, z, rx, ry, rz)
local hash = joaat(model)
RequestModel(hash)
while not HasModelLoaded(hash) do Wait(0) end
local coords = GetEntityCoords(ped)
prop = CreateObject(hash, coords.x, coords.y, coords.z + 0.2, true, true, false)
AttachEntityToEntity(
prop, ped, GetPedBoneIndex(ped, bone),
x, y, z, rx, ry, rz,
true, true, false, true, 1, true
)
SetModelAsNoLongerNeeded(hash)
return prop
endLes pièces :
CreateObject(model, x, y, z, isNetwork, netMissionEntity, doorFlag): passezisNetwork = truesi les autres joueurs doivent voir le prop, ce qui est normalement ce que vous voulez pour quelque chose à la main.GetPedBoneIndex(ped, boneId)convertit un id d'os tel que28422(placement de main droite) ou18905(main gauche) en un index. Cherchez la liste des ids d'os pour les autres.x, y, zetrx, ry, rzsont les décalages et la rotation par rapport à l'os. Ceux-ci doivent être ajustés par prop ; il n'y a pas de raccourci, alors changez une valeur et testez.- Les booléens après la rotation sont des drapeaux d'épinglage mou, de collision et similaires. Collision
falseempêche le prop de pousser le ped autour.
Mettez-le ensemble
local function eatBurger()
local ped = PlayerPedId()
attachProp(ped, 'prop_cs_burger_01', 28422, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
lib.requestAnimDict('mp_player_inteat@burger')
TaskPlayAnim(ped, 'mp_player_inteat@burger', 'mp_player_int_eat_burger', 8.0, -8.0, 3000, 49, 0.0, false, false, false)
Wait(3000)
ClearPedTasks(ped)
deleteProp()
endSi le prop a l'air mauvais à la main, corrigez d'abord les décalages, puis l'os. Si un autre nom d'animation n'existe pas dans un dictionnaire, TaskPlayAnim ne fait silencieusement rien, donc vérifiez deux fois la paire (les noms exacts du dictionnaire et de l'animation, en minuscules comme écrit).
Supprimer le prop
Nettoyez toujours. Un prop qui n'est pas supprimé reste dans le monde, toujours attaché à un ped qui ne le tient plus :
function deleteProp()
if prop and DoesEntityExist(prop) then
DetachEntity(prop, true, true)
DeleteEntity(prop)
end
prop = nil
end
AddEventHandler('onResourceStop', function(resource)
if resource ~= GetCurrentResourceName() then return end
deleteProp()
ClearPedTasks(PlayerPedId())
end)Supprimez aussi le prop à la mort et quand le joueur quitte l'animation, pas seulement sur le chemin heureux. Les props divulgués sont une source classique de « objets partout » et d'un serveur lent ; voir resmon high ms.
Scénarios
Pour les animations debout qui incluent leurs propres props, tels que s'appuyer, fumer ou écrire sur un presse-papiers, utilisez plutôt un scénario :
local ped = PlayerPedId()
TaskStartScenarioInPlace(ped, 'WORLD_HUMAN_CLIPBOARD', 0, true)
-- later
ClearPedTasks(ped)Les arguments sont le ped, le nom du scénario, un délai en ms (0 pour aucun) et si la lecture de l'animation d'entrée. Les scénarios attachent et nettoient leurs props pour vous, et c'est l'option la plus facile quand l'animation n'a pas besoin d'être tenue en marchant.
Pour une version clés en main d'animation plus prop plus barre de progression, la lib.progressBar de ox_lib accepte les options anim et prop ; voir notifications et barres de progression et Wait et threads pour les habitudes d'attente derrière les boucles ci-dessus.
Liste de vérification
| Symptôme | Correction |
|---|---|
| L'animation ne fait rien | Demandez le dictionnaire et attendez d'abord HasAnimDictLoaded |
| La boucle s'accroche au chargement | Le nom du dictionnaire est mauvais ; ajoutez un timeout |
| Le joueur gelé sur place | Le drapeau 0 ou 1 bloque le mouvement ; utilisez 49 pour garder le contrôle |
| Prop aux pieds, pas à la main | Mauvais os ou pas AttachEntityToEntity ; vérifiez GetPedBoneIndex |
| Prop de travers à la main | Affinez les décalages x, y, z et de rotation |
| Props laissés dans le monde | DeleteEntity(prop) à la fin, à la mort et à l'arrêt des ressources |
| Ped bloqué dans une pose | ClearPedTasks ou, en dernier recours, ClearPedTasksImmediately |
Réponses rapides
Pourquoi mon animation ne joue pas ?
Le dictionnaire d'animation n'a pas été chargé encore. Appelez RequestAnimDict, attendez que HasAnimDictLoaded soit vrai, et seulement ensuite appelez TaskPlayAnim. Avec ox_lib, lib.requestAnimDict(dict) le fait pour vous.
Quel drapeau TaskPlayAnim dois-je utiliser ?
Utilisez 1 pour boucler, 16 pour jouer seulement le haut du corps, 32 pour laisser le joueur garder le contrôle, et 49 pour boucle plus haut du corps plus contrôlable. Ce sont les combinaisons courantes pour les animations que vous tenez en marchant.
Comment supprimer un prop après l'animation ?
Appelez DeleteEntity(prop) quand l'animation se termine ou le script s'arrête, et libérez le modèle avec SetModelAsNoLongerNeeded. Les props laissés derrière s'accumulent dans le monde.
Des scripts sans ce problème
Hookah SystemDes chichas et du mobilier lounge à placer, avec plus de 50 saveurs et effets.Voir le script →
Vape SystemPlus de 50 vapes avec saveurs, fumée et effets — de la mangue à la super vitesse.Voir le script →
Super Leaf BlowerUn souffleur de feuilles qui pousse joueurs, voitures, PNJ et props. Compatible avec tous les frameworks.Voir le script →