Animações e props do FiveM: flags TaskPlayAnim, anexar a osso, deletar

Reproduza animações e anexe props no Lua do FiveM: RequestAnimDict, flags TaskPlayAnim 1, 16, 32 e 49, ClearPedTasks, AttachEntityToEntity para um osso, cenários e limpeza.

Você quer que um jogador beba um café, segure um telefone ou use uma ferramenta: uma animação, muitas vezes com um prop na mão. Feito errado, a animação não faz nada, o prop flutua aos pés do jogador ou fica no mundo para sempre. Este guia mostra a sequência de funcionamento e a limpeza.

Carregue, reproduza, limpe

Uma animação vive em um dicionário. O dicionário deve ser carregado antes de você reproduzir a partir dele:

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

Se HasAnimDictLoaded nunca for verdadeiro, o nome do dicionário está errado e este loop trava, então adicione um timeout quando o nome vem de config. Com ox_lib, uma linha substitui o loop:

lua
lib.requestAnimDict('mp_player_inteat@burger')

TaskPlayAnim leva o ped, dicionário, animação, mistura em, mistura fora, duração em ms (-1 = até parar), a flag, e uma taxa de reprodução. Libere o dicionário quando terminar com RemoveAnimDict(dict).

As flags de animação

A flag é uma máscara de bits, então os valores se somam. Os que você usará:

Flag Efeito
0 Reproduzir uma vez, jogador não pode se mover
1 Looping
16 Apenas corpo superior, pernas continuam caminhando
32 Jogador mantém controle
49 1 + 16 + 32: looping, corpo superior, controlável

Para uma animação de segurar na mão (telefone, bebida, cigarro), 49 é a escolha usual: ela faz looping, apenas o corpo superior é animado e o jogador ainda pode caminhar. Para uma ação de tiro único onde o jogador deve ficar de pé, use 0, ou 1 se deve fazer looping.

Parando a animação

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

Use StopAnimTask quando várias coisas rodam no ped, pois ClearPedTasks também cancela a caminhada ou cenário por baixo. ClearPedTasksImmediately conserta um ped travado mas também os tira de veículos, então reserve-a para recuperação.

Um prop na mão

Um prop é um objeto que você cria e anexa a um osso do ped. A sequência: carregue o modelo, crie o objeto, anexe-o, reproduza a animação.

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

As peças:

  • CreateObject(model, x, y, z, isNetwork, netMissionEntity, doorFlag): passe isNetwork = true se outros jogadores devem ver o prop, o que é normalmente o que você quer para algo em uma mão.
  • GetPedBoneIndex(ped, boneId) converte um id de osso como 28422 (posicionamento de mão direita) ou 18905 (mão esquerda) para um índice. Procure a lista de ids de osso para outros.
  • x, y, z e rx, ry, rz são os deslocamentos e rotação relativos ao osso. Estes precisam de ajuste por prop; não há atalho, então altere um valor e teste.
  • Os booleanos após a rotação são fixação suave, colisão e flags semelhantes. Colisão false impede que o prop empurre o ped ao redor.

Junte tudo

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

Se o prop parecer errado na mão, corrija os deslocamentos primeiro, depois o osso. Se outro nome de animação não existir em um dicionário, TaskPlayAnim silenciosamente não faz nada, então verifique o par (os nomes exatos de dicionário e animação, em minúsculas conforme escrito).

Delete o prop

Sempre limpe. Um prop que não é deletado fica no mundo, ainda anexado a um ped que não o segura mais:

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)

Também delete o prop na morte e quando o jogador sai da animação, não apenas no caminho feliz. Props vazados são uma fonte clássica de "objetos em todos os lugares" e um servidor lento; veja resmon high ms.

Cenários

Para animações de pé que incluem seus próprios props, como se inclinar, fumar ou escrever em uma prancheta, use um cenário em vez disso:

lua
local ped = PlayerPedId()
TaskStartScenarioInPlace(ped, 'WORLD_HUMAN_CLIPBOARD', 0, true)

-- later
ClearPedTasks(ped)

Os argumentos são o ped, o nome do cenário, um atraso em ms (0 para nenhum) e se deve reproduzir a animação de entrada. Os cenários anexam e limpam seu prop para você, e são a opção mais fácil quando a animação não precisa ser sustentada enquanto caminha.

Para uma versão pronta de animação mais prop mais barra de progresso, lib.progressBar do ox_lib aceita opções anim e prop; veja notificações e barras de progresso e Wait e threads pelos hábitos de espera por trás dos loops acima.

Lista de verificação

Sintoma Correção
Animação não faz nada Solicite o dicionário e espere que HasAnimDictLoaded seja verdadeiro primeiro
Loop trava no carregamento O nome do dicionário está errado; adicione um timeout
Jogador congelado no lugar Flag 0 ou 1 bloqueia movimento; use 49 para manter controle
Prop nos pés, não na mão Osso errado ou nenhum AttachEntityToEntity; verifique GetPedBoneIndex
Prop torto na mão Sintonize os deslocamentos x, y, z e rotação
Props deixados no mundo DeleteEntity(prop) no fim, morte e parada de recurso
Ped preso em uma pose ClearPedTasks ou, como último recurso, ClearPedTasksImmediately

Respostas rápidas

Por que minha animação não toca?

O dicionário de animação ainda não foi carregado. Chame RequestAnimDict, espere até que HasAnimDictLoaded seja verdadeiro, e apenas então chame TaskPlayAnim. Com ox_lib, lib.requestAnimDict(dict) faz isso para você.

Qual flag TaskPlayAnim devo usar?

Use 1 para looping, 16 apenas para o corpo superior, 32 para deixar o jogador com controle e 49 para looping mais corpo superior mais controlável. Estas são as combinações comuns para animações que você segura enquanto caminha.

Como removo um prop após a animação?

Chame DeleteEntity(prop) quando a animação terminar ou o script parar, e libere o modelo com SetModelAsNoLongerNeeded. Props deixados para trás se acumulam no mundo.

Scripts sem esse problema

Hookah SystemNarguilés e móveis de lounge posicionáveis, com mais de 50 sabores e efeitos.Ver script →Vape SystemMais de 50 vapes com sabores, fumaça e efeitos — de manga a supervelocidade.Ver script →Super Leaf BlowerUm soprador de folhas que empurra jogadores, carros, NPCs e props. Funciona em qualquer framework.Ver script →

Continue lendo