games / fivem
Natives essentielles : joueur, ped, véhicules, monde
Explication
Ce que vous allez apprendre
- Récupérer le ped du joueur et sa position avec
PlayerPedId/GetEntityCoords - Manipuler un véhicule (verrouillage, carburant, moteur) via les natives dédiées
- Charger un modèle correctement avec
RequestModelavant de créer un véhicule ou un ped - Libérer un modèle chargé avec
SetModelAsNoLongerNeededpour éviter les fuites mémoire - Ajouter un blip sur la carte et détecter ce qu'un joueur regarde (raycast)
Dans quel contexte ?
Un script doit faire apparaître un véhicule spécifique à un endroit précis dès qu'un joueur tape une commande, avec une icône correspondante sur la carte. Ce cas d'usage très courant illustre parfaitement le cycle de vie d'un modèle FiveM : demander son chargement, attendre qu'il soit prêt, créer l'objet, puis libérer la mémoire une fois que ce n'est plus nécessaire — une séquence que beaucoup de débutants raccourcissent par erreur, avec des objets invisibles ou des crashs à la clé.
| Native | Rôle |
|---|---|
PlayerPedId() | Entité contrôlée localement (client uniquement) |
RequestModel(hash) | Demande le chargement d'un modèle en mémoire |
HasModelLoaded(hash) | Vérifie si le chargement est terminé |
SetModelAsNoLongerNeeded(hash) | Libère la mémoire du modèle après usage |
Piège fréquent
Appeler CreateVehicle ou CreatePed immédiatement après RequestModel, sans attendre HasModelLoaded dans une boucle, crée souvent un objet invisible ou provoque une erreur silencieuse : le modèle n'a pas encore fini de se charger depuis le disque ou le réseau.
Le vocabulaire du moteur de jeu
Le jeu GTA V, sur lequel FiveM repose, est lui-même écrit dans un autre langage (C++). Pour permettre au code Lua d'interagir avec ce moteur — déplacer un personnage, faire apparaître un véhicule, dessiner une icône sur la carte — FiveM expose des milliers de fonctions prêtes à l'emploi appelées natives. Une native n'est donc pas une fonction qu'on écrit soi-même : c'est une porte d'entrée déjà construite vers une fonctionnalité du jeu.
PlayerPedId : le point de départ de presque tout
PlayerPedId() est probablement la native la plus utilisée en scripting client : elle retourne l'identifiant du personnage ("ped", pour "pedestrian") que le joueur contrôle actuellement. Un point important vu dans la leçon précédente : cette native n'a de sens que côté client, puisque le serveur ne connaît rien du monde 3D.
Pourquoi charger un modèle prend du temps
Créer un véhicule ou un personnage à partir d'un modèle 3D n'est pas instantané : ce modèle doit d'abord être "streamé", c'est-à-dire chargé en mémoire depuis le disque ou le réseau. C'est pour cela qu'on doit systématiquement demander le chargement (RequestModel) puis attendre, dans une petite boucle, que ce chargement soit effectivement terminé, avant de tenter de créer l'objet — sauter cette étape crée des objets invisibles ou provoque des erreurs.
Ne pas oublier de libérer la mémoire
Une fois un modèle utilisé, il reste chargé en mémoire tant qu'on ne signale pas explicitement qu'on n'en a plus besoin (SetModelAsNoLongerNeeded). Sur un serveur où des dizaines de scripts créent régulièrement des véhicules ou des personnages, oublier cette étape provoque une accumulation progressive de mémoire utilisée pour rien — un classique des ressources mal écrites qui finissent par ralentir tout le serveur au fil du temps.
Commandes & code
Natives essentielles
Les "natives" sont les fonctions du moteur du jeu, exposées à Lua. Voici les plus utilisées côté client.
-- Joueur et ped
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
local heading = GetEntityHeading(ped)
SetEntityCoords(ped, coords.x + 5.0, coords.y, coords.z, false, false, false, true)
SetEntityHeading(ped, 180.0)
-- Santé / armure
SetEntityHealth(ped, 200)
SetPedArmour(ped, 100)-- Véhicules
local vehicle = GetVehiclePedIsIn(ped, false)
if vehicle ~= 0 then
SetVehicleFuelLevel(vehicle, 100.0)
SetVehicleDoorsLocked(vehicle, 2) -- 2 = verrouillé
SetVehicleEngineOn(vehicle, true, true, false)
end
-- Spawn d'un véhicule (pattern classique de chargement de modèle)
local function SpawnVehicle(model, coords, heading)
local hash = GetHashKey(model)
RequestModel(hash)
while not HasModelLoaded(hash) do
Wait(10) -- attendre le streaming du modèle, sans bloquer le jeu (voir leçon Threads)
end
local veh = CreateVehicle(hash, coords.x, coords.y, coords.z, heading, true, false)
SetModelAsNoLongerNeeded(hash) -- libère la mémoire une fois le véhicule créé
return veh
end
local myCar = SpawnVehicle('adder', vector3(215.0, -810.0, 30.0), 90.0)-- Blips (icônes sur la carte)
local blip = AddBlipForCoord(coords.x, coords.y, coords.z)
SetBlipSprite(blip, 1)
SetBlipColour(blip, 2)
SetBlipScale(blip, 0.8)
SetBlipAsShortRange(blip, true)
BeginTextCommandSetBlipName("STRING")
AddTextComponentString("Boutique Technologik")
EndTextCommandSetBlipName(blip)-- Raycast : détecter ce que le joueur regarde (utilisé pour les interactions custom)
local function GetEntityPlayerIsLookingAt()
local ped = PlayerPedId()
local coords = GetEntityCoords(ped)
local camRot = GetGameplayCamRot(2)
local camCoord = GetGameplayCamCoord()
local direction = RotationToDirection(camRot)
local destination = camCoord + direction * 10.0
local rayHandle = StartShapeTestRay(
camCoord.x, camCoord.y, camCoord.z,
destination.x, destination.y, destination.z,
-1, ped, 0
)
local _, hit, _, _, entity = GetShapeTestResult(rayHandle)
if hit == 1 then
return entity
end
return nil
endRésumé
PlayerPedId()retourne l'entité contrôlée localement ; jamais valable côté serveur.- Toujours utiliser
RequestModel+ boucle d'attente avantCreateVehicle/CreatePedavec un nouveau modèle. - Libérer les modèles avec
SetModelAsNoLongerNeededpour éviter les fuites mémoire.
Exercices pratiques
Mission : le véhicule qui apparaît invisible
Objectif : Corriger un cycle de chargement de modèle incomplet responsable d'un véhicule invisible et d'une fuite mémoire progressive.
Contexte
La commande /car adder d'un serveur de test spawn parfois un véhicule invisible ou provoque un léger freeze. Le code en cause est : RequestModel(GetHashKey('adder')); local veh = CreateVehicle(GetHashKey('adder'), x, y, z, heading, true, false), appelé directement l'un après l'autre, sans jamais libérer le modèle ensuite. La boutique de véhicules du serveur, qui utilise le même pattern des dizaines de fois par jour, voit la consommation mémoire du client augmenter lentement au fil des sessions.