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 :

lua
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
end

Les étapes :

  1. IsModelInCdimage vérifie que le modèle existe. Une faute de frappe ou une voiture addon manquante s'arrête ici au lieu de geler.
  2. RequestModel puis une boucle sur HasModelLoaded attend, avec un délai d'attente.
  3. CreateVehicle prend le modèle, la position, la direction, puis isNetwork (true pour que les autres joueurs la voient) et netMissionEntity.
  4. SetModelAsNoLongerNeeded libè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 :

lua
local vehicle = spawnVehicle('sultan', GetEntityCoords(PlayerPedId()), GetEntityHeading(PlayerPedId()))

if vehicle then
    SetVehicleNumberPlateText(vehicle, 'MIC 001')
    SetPedIntoVehicle(PlayerPedId(), vehicle, -1)
end

La 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 :

lua
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 :

lua
-- server
local netId = NetworkGetNetworkIdFromEntity(vehicle)

Sur le client, attendez que l'entité existe sur cette machine, puis convertissez :

lua
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 :

  1. Créer le véhicule.
  2. Définir la plaque avec SetVehicleNumberPlateText.
  3. 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 :

lua
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 :

lua
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.

Des scripts sans ce problème

Advanced BoostingDu boosting de véhicules piloté par tablette : contrats de classe D à S+, crews et file d’attente en direct.Voir le script →Chameleon Paints82 peintures caméléon à reflets changeants, dans un menu à appliquer en un clic.Voir le script →

À lire aussi