Parent : [[INDEX-FIVEM-GAMEPLAY]]
FiveM - Ragdoll + Props Persistence : keymapping, sauvegarde props véhicule, animation timeout
Problème
Le ragdoll (tomber au sol) doit être toggleable via keymapping, et les props du joueur (chapeau) doivent être restaurés après être sorti d'un véhicule. Le chargement d'animations nécessite un timeout pour éviter les freezes.
Solution
Système ragdoll toggle avec keymapping RegisterKeyMapping, sauvegarde de props (chapeau) avant/pendant véhicule, timeout de chargement d'animations.
-- CKCore/client/cl_utils.lua
local ESX = exports["es_extended"]:getSharedObject()
local ragdoll = false
local savedHat = -1
local savedHatTexture = 0
local wasInVehicle = false
-- =========================================================
-- ANIMATION LOADER AVEC TIMEOUT
-- =========================================================
local function LoadAnimDict(dict, timeout)
timeout = timeout or 5000
if HasAnimDictLoaded(dict) then return true end
RequestAnimDict(dict)
local start = GetGameTimer()
while not HasAnimDictLoaded(dict) do
Wait(50)
if GetGameTimer() - start > timeout then
print('[^1ERROR^7] Failed to load anim dict: ' .. dict)
return false
end
end
return true
end
-- =========================================================
-- RAGDOLL SYSTEM
-- =========================================================
CreateThread(function()
while true do
if ragdoll then
local ped = PlayerPedId()
if not IsPedInAnyVehicle(ped, false) then
SetPedToRagdoll(ped, 1000, 1000, 0, false, false, false)
ESX.ShowHelpNotification("Appuyez sur ~r~[ESPACE]~s~ pour vous relever")
if IsControlJustPressed(0, 22) then -- INPUT_JUMP (SPACE)
ragdoll = false
end
Wait(0)
else
ragdoll = false
Wait(250)
end
else
Wait(500)
end
end
end)
RegisterNetEvent('dh_ragdoll:toggle')
AddEventHandler('dh_ragdoll:toggle', function()
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then return end
ragdoll = not ragdoll
end)
RegisterCommand('ragdoll', function()
local ped = PlayerPedId()
if not IsPedInAnyVehicle(ped, false) then
TriggerEvent("dh_ragdoll:toggle")
else
ESX.ShowNotification("Vous ne pouvez pas tomber au sol dans un véhicule.")
end
end, false)
-- Keymapping native (visible dans les paramètres FiveM)
RegisterKeyMapping('ragdoll', "Tomber par terre / se relever", 'keyboard', 'PLUS')
-- =========================================================
-- SAUVEGARDE CHAPEAU EN VEHICULE
-- =========================================================
CreateThread(function()
while true do
local ped = PlayerPedId()
local inVehicle = IsPedInAnyVehicle(ped, false)
if not inVehicle then
-- Sauvegarde quand on est hors véhicule
if not wasInVehicle then
savedHat = GetPedPropIndex(ped, 0)
savedHatTexture = GetPedPropTextureIndex(ped, 0)
end
wasInVehicle = false
Wait(500)
else
-- Entrée véhicule : on a déjà sauvegardé avant
if not wasInVehicle then
wasInVehicle = true
-- Le chapeau est retiré par GTA native, on le restaure à la sortie
end
Wait(1000)
end
end
end)
-- Restauration chapeau à la sortie de véhicule
AddEventHandler('gameEventTriggered', function(name, args)
if name == 'CEventNetworkPlayerEnteredVehicle' then
-- Entrée : rien à faire, GTA gère
elseif name == 'CEventNetworkPlayerLeftVehicle' then
-- Sortie : restauration
local ped = PlayerPedId()
if savedHat ~= -1 then
SetPedPropIndex(ped, 0, savedHat, savedHatTexture, true)
end
end
end)
Pourquoi
RegisterKeyMappingexpose le bind dans le menu native de FiveM- Timeout 5s sur
LoadAnimDictévite le freeze infini si le dict est corrompu - Sauvegarde chapeau préserve l'apparence du joueur après véhicule
Quand l'utiliser
- Émotes interactives (sit, lay, lean)
- Systèmes de props persistants (lunettes, masques)
- Keybindings pour actions RP
Quand NE PAS l'utiliser
- Animations one-shot sans toggle → pas besoin de keymapping
Exemples
Correct
-- Animation loader générique réutilisable
function PlayAnimation(ped, dict, anim, blendIn, blendOut, duration, flag)
if not LoadAnimDict(dict, 3000) then
print('Animation impossible à charger')
return false
end
TaskPlayAnim(ped, dict, anim, blendIn or 8.0, blendOut or -8.0, duration or -1, flag or 0, 0, false, false, false)
return true
end
-- Usage
RegisterCommand('sit', function()
local ped = PlayerPedId()
if PlayAnimation(ped, 'anim@heists@prison_heistunfinished_biztarget_idle', 'target_idle') then
-- Animation jouée avec succès
end
end, false)
Incorrect
-- Pas de timeout → freeze si le dict n'existe pas
function BadLoadAnim(dict)
RequestAnimDict(dict)
while not HasAnimDictLoaded(dict) do
Wait(0) -- Freeze potentiellement infini
end
end
Références
- CKCore/client/cl_utils.lua L9-65
- CKCore/config.lua L1-80