Animaciones y props de FiveM: banderas de TaskPlayAnim, adjuntar a hueso, eliminar

Reproduce animaciones y adjunta props en FiveM Lua: RequestAnimDict, banderas de TaskPlayAnim 1, 16, 32 y 49, ClearPedTasks, AttachEntityToEntity a un hueso, escenarios y limpieza.

Quieres que un jugador beba un café, sostenga un teléfono o use una herramienta: una animación, a menudo con un prop en la mano. Hecho mal, la animación no hace nada, el prop flota a los pies del jugador o se queda en el mundo para siempre. Esta guía muestra la secuencia de trabajo y la limpieza.

Cargar, reproducir, limpiar

Una animación vive en un diccionario. El diccionario debe cargarse antes de reproducir desde él:

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 nunca es verdadero, el nombre del diccionario es incorrecto y este bucle se cuelga, así que añade un timeout cuando el nombre viene de la configuración. Con ox_lib, una línea reemplaza el bucle:

lua
lib.requestAnimDict('mp_player_inteat@burger')

TaskPlayAnim toma el ped, diccionario, animación, mezcla en, mezcla fuera, duración en ms (-1 = hasta que se detenga), la bandera, y una velocidad de reproducción. Libera el diccionario cuando termines con RemoveAnimDict(dict).

Las banderas de animación

La bandera es una máscara de bits, así que los valores se suman. Las que usarás:

Bandera Efecto
0 Reproducir una vez, el jugador no puede moverse
1 Bucle
16 Solo cuerpo superior, las piernas siguen caminando
32 El jugador mantiene el control
49 1 + 16 + 32: bucle, cuerpo superior, controlable

Para una animación de sostener en la mano (teléfono, bebida, cigarrillo), 49 es la opción habitual: se repite, solo el cuerpo superior está animado, y el jugador aún puede caminar. Para una acción única donde el jugador debe estar quieto, usa 0, o 1 si debe repetirse.

Detener la animación

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

Usa StopAnimTask cuando varias cosas se ejecutan en el ped, ya que ClearPedTasks también cancela la caminata o el escenario debajo. ClearPedTasksImmediately fija un ped atascado pero también los saca de los vehículos, así que guárdalo para la recuperación.

Un prop en la mano

Un prop es un objeto que creas y adjuntas a un hueso del ped. La secuencia: carga el modelo, crea el objeto, adjúntalo, reproduce la animación.

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

Los pedazos:

  • CreateObject(model, x, y, z, isNetwork, netMissionEntity, doorFlag): pasa isNetwork = true si otros jugadores deben ver el prop, que es normalmente lo que quieres para algo en una mano.
  • GetPedBoneIndex(ped, boneId) convierte un id de hueso como 28422 (colocación de mano derecha) o 18905 (mano izquierda) en un índice. Busca la lista de id de hueso para otros.
  • x, y, z y rx, ry, rz son los desplazamientos y rotación relativos al hueso. Estos necesitan sintonización por prop; no hay atajo, así que cambia un valor y prueba.
  • Los booleanos después de la rotación son fijación suave, colisión y banderas similares. La colisión false previene que el prop empuje al ped alrededor.

Juntalo todo

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 el prop se ve mal en la mano, arregla primero los desplazamientos, luego el hueso. Si otro nombre de animación no existe en un diccionario, TaskPlayAnim silenciosamente no hace nada, así que verifica dos veces el par (el diccionario exacto y los nombres de animación, en minúsculas como está escrito).

Elimina el prop

Siempre limpia. Un prop que no se elimina se queda en el mundo, aún adjunto a un ped que ya no lo sostiene:

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)

También elimina el prop en la muerte y cuando el jugador deja la animación, no solo en el camino feliz. Los props filtrados son una fuente clásica de «objetos por todas partes» y un servidor lento; ve resmon high ms.

Escenarios

Para animaciones de pie que incluyen sus propios props, como apoyarse, fumar o escribir en un portapapeles, usa un escenario en su lugar:

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

-- later
ClearPedTasks(ped)

Los argumentos son el ped, el nombre del escenario, un retraso en ms (0 para ninguno) y si se reproduce la animación de entrada. Los escenarios adjuntan y limpian su prop por ti, y son la opción más fácil cuando la animación no necesita ser sostenida mientras caminas.

Para una versión lista de animación más prop más barra de progreso, la lib.progressBar de ox_lib acepta opciones anim y prop; ve notifications and progress bars y Wait and threads para los hábitos de espera detrás de los bucles anteriores.

Lista de verificación

Síntoma Solución
La animación no hace nada Solicita el diccionario y espera a que HasAnimDictLoaded sea verdadero primero
El bucle se cuelga al cargar El nombre del diccionario es incorrecto; añade un timeout
El jugador congelado en su lugar La bandera 0 o 1 bloquea el movimiento; usa 49 para mantener el control
Prop a los pies, no a la mano Hueso incorrecto o sin AttachEntityToEntity; comprueba GetPedBoneIndex
Prop torcido en la mano Sintoniza los desplazamientos x, y, z y rotación
Props abandonados en el mundo DeleteEntity(prop) al final, muerte e parada del recurso
Ped atascado en una postura ClearPedTasks o, como último recurso, ClearPedTasksImmediately

Respuestas rápidas

¿Por qué mi animación no se reproduce?

El diccionario de animación aún no se cargó. Llama a RequestAnimDict, espera hasta que HasAnimDictLoaded sea verdadero, y solo entonces llama a TaskPlayAnim. Con ox_lib, lib.requestAnimDict(dict) hace esto por ti.

¿Qué bandera de TaskPlayAnim debo usar?

Usa 1 para bucle, 16 para reproducir solo en el cuerpo superior, 32 para permitir que el jugador mantenga el control, y 49 para bucle más cuerpo superior más controlable. Estas son las combinaciones comunes para animaciones que sostienes mientras caminas.

¿Cómo elimino un prop después de la animación?

Llama a DeleteEntity(prop) cuando termina la animación o el script se detiene, y libera el modelo con SetModelAsNoLongerNeeded. Los props abandonados se apilan en el mundo.

Scripts que evitan este problema

Hookah SystemCachimbas y muebles de lounge colocables, con más de 50 sabores y efectos.Ver script →Vape SystemMás de 50 vapers con sabores, humo y efectos — del mango a la súper velocidad.Ver script →Super Leaf BlowerUn soplador que empuja jugadores, coches, NPCs y props. Funciona en cualquier framework.Ver script →

Sigue leyendo