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 :

lua
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)
end

Si 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 :

lua
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

lua
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 animation

Utilisez 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.

lua
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
end

Les pièces :

  • CreateObject(model, x, y, z, isNetwork, netMissionEntity, doorFlag) : passez isNetwork = true si 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 que 28422 (placement de main droite) ou 18905 (main gauche) en un index. Cherchez la liste des ids d'os pour les autres.
  • x, y, z et rx, ry, rz sont 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 false empêche le prop de pousser le ped autour.

Mettez-le ensemble

lua
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()
end

Si 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 :

lua
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 :

lua
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 →

À lire aussi