Animazioni e prop di FiveM: flag TaskPlayAnim, attacca all'osso, elimina
Riproduci animazioni e attacca prop in FiveM Lua: RequestAnimDict, flag TaskPlayAnim 1, 16, 32 e 49, ClearPedTasks, AttachEntityToEntity a un osso, scenari e pulizia.
Vuoi che un giocatore beva un caffè, tenga un telefono o usi uno strumento: un'animazione, spesso con un prop nella mano. Se fatto male, l'animazione non fa nulla, il prop galleggia ai piedi del giocatore o rimane nel mondo per sempre. Questa guida mostra la sequenza corretta e la pulizia.
Carica, riproduci, cancella
Un'animazione vive in un dizionario. Il dizionario deve essere caricato prima di riprodurre da esso:
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)
endSe HasAnimDictLoaded non è mai true, il nome del dizionario è sbagliato e questo ciclo si blocca, quindi aggiungi un timeout quando il nome proviene dalla config. Con ox_lib, una riga sostituisce il ciclo:
lib.requestAnimDict('mp_player_inteat@burger')TaskPlayAnim accetta il ped, il dizionario, l'animazione, il blend in, il blend out, la durata in ms (-1 = fino a quando non fermato), il flag, e una velocità di riproduzione. Rilascia il dizionario quando hai finito con RemoveAnimDict(dict).
I flag di animazione
Il flag è una bitmask, quindi i valori si sommano. Quelli che utilizzerai:
| Flag | Effetto |
|---|---|
| 0 | Riproduci una volta, il giocatore non può muoversi |
| 1 | Loop |
| 16 | Solo corpo superiore, le gambe continuano a camminare |
| 32 | Il giocatore mantiene il controllo |
| 49 | 1 + 16 + 32: loop, corpo superiore, controllabile |
Per un'animazione da tenere in mano (telefono, drink, sigaretta), 49 è la scelta solita: fa il loop, solo il corpo superiore è animato, e il giocatore può ancora camminare. Per un'azione one-shot dove il giocatore dovrebbe stare fermo, usa 0, o 1 se dovrebbe fare il loop.
Interrompi l'animazione
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 animationUsa StopAnimTask quando diverse cose vengono eseguite sul ped, poiché ClearPedTasks annulla anche la camminata o lo scenario sottostante. ClearPedTasksImmediately corregge un ped bloccato ma lo fa anche uscire dai veicoli, quindi conservalo per il recupero.
Un prop nella mano
Un prop è un oggetto che crei e attacchi a un osso del ped. La sequenza: carica il modello, crea l'oggetto, attaccalo, riproduci l'animazione.
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
endI pezzi:
CreateObject(model, x, y, z, isNetwork, netMissionEntity, doorFlag): passaisNetwork = truese altri giocatori dovrebbero vedere il prop, che è normalmente quello che vuoi per qualcosa in una mano.GetPedBoneIndex(ped, boneId)converte un id osso come28422(posizionamento mano destra) o18905(mano sinistra) in un indice. Cerca l'elenco degli id osso per altri.x, y, zerx, ry, rzsono gli offset e la rotazione relativi all'osso. Questi hanno bisogno di messa a punto per prop; non c'è scorciatoia, quindi cambia un valore e prova.- I booleani dopo la rotazione sono soft pinning, collisione e flag simili. Collisione
falseimpedisce al prop di spingere il ped in giro.
Mettilo insieme
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()
endSe il prop non sembra giusto nella mano, correggi prima gli offset, poi l'osso. Se il nome di un'altra animazione non esiste in un dizionario, TaskPlayAnim non fa silenziosamente nulla, quindi controlla doppiamente la coppia (i nomi esatti del dizionario e dell'animazione, in minuscolo come scritto).
Elimina il prop
Pulisci sempre. Un prop che non viene eliminato rimane nel mondo, ancora attaccato a un ped che non lo tiene più:
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)Elimina anche il prop alla morte e quando il giocatore esce dall'animazione, non solo sul percorso felice. I prop persi sono una fonte classica di "oggetti ovunque" e un server lento; vedi resmon high ms.
Scenari
Per le animazioni in piedi che includono i loro prop, come appoggiarsi, fumare o scrivere su una lavagna, usa un scenario invece:
local ped = PlayerPedId()
TaskStartScenarioInPlace(ped, 'WORLD_HUMAN_CLIPBOARD', 0, true)
-- later
ClearPedTasks(ped)Gli argomenti sono il ped, il nome dello scenario, un ritardo in ms (0 per nessuno) e se riprodurre l'animazione di entrata. Gli scenari attaccano e puliscono il loro prop per te, e sono l'opzione più facile quando l'animazione non ha bisogno di essere tenuta mentre cammini.
Per una versione pronta di animazione più prop più barra di progresso, lib.progressBar di ox_lib accetta le opzioni anim e prop; vedi notifiche e barre di progresso e Aspetta e thread per le abitudini di attesa dietro i cicli sopra.
Checklist
| Sintomo | Soluzione |
|---|---|
| L'animazione non fa nulla | Richiedi il dizionario e aspetta che HasAnimDictLoaded sia true prima |
| Il ciclo si blocca al caricamento | Il nome del dizionario è sbagliato; aggiungi un timeout |
| Giocatore congelato sul posto | Flag 0 o 1 blocca il movimento; usa 49 per mantenere il controllo |
| Prop ai piedi, non alla mano | Osso sbagliato o nessun AttachEntityToEntity; controlla GetPedBoneIndex |
| Prop storto nella mano | Messa a punto x, y, z e offset di rotazione |
| Prop rimasti nel mondo | DeleteEntity(prop) alla fine, morte e arresto della risorsa |
| Ped bloccato in una posa | ClearPedTasks o, come ultimo ricorso, ClearPedTasksImmediately |
Risposte rapide
Perché la mia animazione non viene riprodotta?
Il dizionario di animazioni non era ancora caricato. Chiama RequestAnimDict, aspetta fino a quando HasAnimDictLoaded è true, e solo allora chiama TaskPlayAnim. Con ox_lib, lib.requestAnimDict(dict) lo fa per te.
Quale flag TaskPlayAnim dovrei usare?
Usa 1 per il loop, 16 per riprodurre solo il corpo superiore, 32 per lasciare il giocatore in controllo, e 49 per loop più corpo superiore più controllabile. Queste sono le combinazioni comuni per le animazioni che tieni mentre cammini.
Come rimuovo un prop dopo l'animazione?
Chiama DeleteEntity(prop) quando l'animazione termina o lo script si ferma, e rilascia il modello con SetModelAsNoLongerNeeded. I prop rimasti accumulano nel mondo.
Script senza questo problema
Hookah SystemNarghilè e arredi lounge posizionabili, con oltre 50 gusti ed effetti.Vedi script →
Vape SystemOltre 50 svapo con gusti, fumo ed effetti — dal mango alla super velocità.Vedi script →
Super Leaf BlowerUn soffiatore che spinge giocatori, auto, NPC e props. Funziona con qualsiasi framework.Vedi script →