Générer un véhicule dans FiveM : CreateVehicle vs CreateVehicleServerSetter
Générez des véhicules de la bonne façon dans FiveM : client CreateVehicle avec RequestModel, serveur CreateVehicleServerSetter sur OneSync, net ids, plaques d'immatriculation, clés et voitures qui disparaissent.
Vous générez un véhicule et il apparaît invisible, se génère sous la carte, disparaît après une minute, ou seul le joueur qui l'a généré peut le voir. Il y a deux façons correctes de générer une voiture, et chacune a un ensemble différent de pièges. Cet article montre les deux, comment définir la plaque et remettre les clés, et pourquoi les voitures générées disparaissent.
Générer sur le client avec CreateVehicle
La version client est celle que la plupart des scripts utilisent. Le modèle doit être chargé avant de créer le véhicule, ou CreateVehicle retourne 0 :
local function spawnVehicle(modelName, coords, heading)
local model = joaat(modelName)
if not IsModelInCdimage(model) or not IsModelAVehicle(model) then
print('invalid vehicle model:', modelName)
return nil
end
RequestModel(model)
local timeout = GetGameTimer() + 5000
while not HasModelLoaded(model) do
if GetGameTimer() > timeout then
print('model did not load:', modelName)
return nil
end
Wait(0)
end
local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false)
SetModelAsNoLongerNeeded(model)
return vehicle
endLes étapes :
IsModelInCdimagevérifie que le modèle existe. Une faute de frappe ou une voiture addon manquante s'arrête ici au lieu de geler.RequestModelpuis une boucle surHasModelLoadedattend, avec un délai d'attente.CreateVehicleprend le modèle, la position, la direction, puisisNetwork(truepour que les autres joueurs la voient) etnetMissionEntity.SetModelAsNoLongerNeededlibère la mémoire du modèle quand vous avez terminé.
Si le véhicule est un addon, voir comment ajouter des voitures addon d'abord. Un modèle qui n'est pas en streaming ne charge jamais.
Conseil : avec ox_lib,
lib.requestModel(model)fait la demande et l'attente pour vous, et erreurs en cas de délai d'attente.
Mettez le joueur sur le siège du conducteur et définissez la plaque :
local vehicle = spawnVehicle('sultan', GetEntityCoords(PlayerPedId()), GetEntityHeading(PlayerPedId()))
if vehicle then
SetVehicleNumberPlateText(vehicle, 'MIC 001')
SetPedIntoVehicle(PlayerPedId(), vehicle, -1)
endLa plaque peut contenir au maximum 8 caractères.
Générer sur le serveur avec CreateVehicleServerSetter
Sur OneSync, le serveur peut créer le véhicule lui-même. C'est plus fiable pour les scripts où le serveur décide du spawn, comme un garage ou un véhicule de travail, et aucun client n'a besoin de rester près :
RegisterNetEvent('my_script:spawnCar', function()
local src = source
local ped = GetPlayerPed(src)
local coords = GetEntityCoords(ped)
local heading = GetEntityHeading(ped)
local vehicle = CreateVehicleServerSetter(joaat('sultan'), 'automobile', coords.x, coords.y, coords.z, heading)
while not DoesEntityExist(vehicle) do
Wait(0)
end
SetVehicleNumberPlateText(vehicle, 'MIC 001')
TaskWarpPedIntoVehicle(ped, vehicle, -1)
local netId = NetworkGetNetworkIdFromEntity(vehicle)
TriggerClientEvent('my_script:vehicleSpawned', src, netId)
end)Le deuxième argument est le type de véhicule sous forme de chaîne : 'automobile', 'bike', 'boat', 'heli', 'plane', 'submarine', 'trailer' ou 'train'. Choisissez celui qui correspond au modèle. Une moto créée en tant qu'automobile se comportera mal.
Contrairement au client, vous ne demandez pas le modèle sur le serveur. L'appel est également asynchrone : l'entité peut ne pas exister au moment où il retourne, donc attendez DoesEntityExist, avec un délai d'attente dans le code réel.
Activez OneSync dans server.cfg, ou l'appel ne fonctionne pas. Voir comment activer OneSync.
Net ids : remettre la voiture à un client
Un véhicule créé sur le serveur a un identifiant d'entité qui n'existe que sur le serveur. Un client ne peut pas l'utiliser. Pour référencer la voiture sur les machines, utilisez son network id, qui est le même partout :
-- server
local netId = NetworkGetNetworkIdFromEntity(vehicle)Sur le client, attendez que l'entité existe sur cette machine, puis convertissez :
RegisterNetEvent('my_script:vehicleSpawned', function(netId)
local timeout = GetGameTimer() + 5000
while not NetworkDoesEntityExistWithNetworkId(netId) do
if GetGameTimer() > timeout then return end
Wait(0)
end
local vehicle = NetToVeh(netId)
print('my vehicle is', vehicle)
end)N'envoyez jamais l'identifiant d'entité brut sur un événement : cela ne signifie rien sur une autre machine.
Plaques et clés
Définissez la plaque juste après que le véhicule existe, comme dans les exemples ci-dessus, et avant de remettre les clés. Les clés dépendent de votre script de clés de véhicule, puisque chaque script a sa propre fonction. La plupart fonctionnent avec la plaque, donc l'ordre habituel est :
- Créer le véhicule.
- Définir la plaque avec
SetVehicleNumberPlateText. - Appelez la fonction d'export ou d'événement de votre script de clés avec cette plaque.
Stockez la même plaque dans votre base de données, si le véhicule est possédé, pour que le garage puisse le trouver à nouveau. Vérifiez la documentation du script de clés que vous utilisez pour l'appel exact. Ne copiez pas un appel d'un autre serveur.
Pourquoi les voitures générées disparaissent
Pas pertinent pour quelqu'un. Le jeu supprime une entité en réseau quand personne n'en est près. Une voiture générée sur le serveur pour un joueur qui s'éloigne ensuite peut être supprimée.
Le propriétaire a quitté. Une entité appartient à un joueur qui la possède. Quand un propriétaire de véhicule généré par le client se déconnecte ou s'éloigne, il peut être supprimé. Sur le serveur, vous pouvez définir ce qui se passe :
SetEntityOrphanMode(vehicle, 2)Le mode orphelin 2 est « garder l'entité », 0 est le défaut (supprimer quand non pertinent), et 1 la supprime quand le propriétaire se déconnecte. Vérifiez la documentation du natif pour votre version serveur.
Pas marqué comme entité de mission. Sur le client, le nettoyage ambiant peut supprimer une voiture que vous avez créée. Marquez-la pour que le jeu la traite comme la vôtre :
SetEntityAsMissionEntity(vehicle, true, true)Un script de nettoyage. De nombreux serveurs exécutent un script qui supprime les véhicules inoccupés. Si vos voitures disparaissent à une heure fixe, c'en est la cause, pas votre code de génération.
Il n'a jamais été généré. Une voiture invisible ou manquante signifie souvent que le modèle n'a pas été chargé, CreateVehicle a retourné 0 et le script a continué. Vérifiez toujours l'identifiant retourné.
Supprimez les voitures vous-même quand vous avez terminé, avec DeleteEntity(vehicle), pour qu'elles ne s'accumulent pas.
Liste de contrôle
| Symptôme | Solution |
|---|---|
CreateVehicle retourne 0 |
RequestModel et attendez HasModelLoaded en premier |
| Gel sur un mauvais nom de modèle | Vérifiez IsModelInCdimage avant de demander |
| Seul le spawn voit la voiture | Passez isNetwork = true à CreateVehicle |
CreateVehicleServerSetter ne fait rien |
Activez OneSync et attendez DoesEntityExist |
| Le client reçoit un identifiant d'entité inutile | Envoyez le net id, puis utilisez NetToVeh sur le client |
| La voiture disparaît plus tard | Marquez comme entité de mission, définissez le mode orphelin, vérifiez les scripts de nettoyage |
| Le joueur ne peut pas conduire sa voiture | Donnez les clés avec votre script de clés, en utilisant la plaque |
Réponses rapides
Ai-je besoin de OneSync pour utiliser CreateVehicleServerSetter ?
Oui. La création d'entité côté serveur nécessite OneSync activé. Sur un serveur sans lui, générez le véhicule sur le client avec CreateVehicle.
Pourquoi ma voiture générée disparaît-elle ?
Un véhicule en réseau est supprimé quand il n'est plus pertinent pour personne, ou quand son propriétaire part, à moins que vous disiez au jeu de le garder. Marquez-le comme une entité de mission sur le client, ou définissez son mode orphelin sur le serveur.
Comment donner les clés au joueur ?
Cela dépend du script de clés de véhicule que votre serveur utilise. La plupart ont une export ou un événement client qui prend la plaque, alors appelez cela après avoir défini la plaque.

