Desova un vehículo en FiveM: CreateVehicle vs CreateVehicleServerSetter

Desova vehículos de la forma correcta en FiveM: CreateVehicle del cliente con RequestModel, CreateVehicleServerSetter del servidor en OneSync, net ids, plates, keys y coches que desaparecen.

Desovas un vehículo y aparece invisible, se desova bajo el mapa, desaparece después de un minuto, o solo el jugador que lo desovó puede verlo. Hay dos formas correctas de desova un coche, y cada una tiene un conjunto diferente de problemas. Este artículo muestra ambas, cómo establecer la matrícula y entregar las llaves, y por qué los coches desovados desaparecen.

Desova en el cliente con CreateVehicle

La versión del cliente es la que usa la mayoría de scripts. El modelo debe estar cargado antes de crear el vehículo, o CreateVehicle devuelve 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

Los pasos:

  1. IsModelInCdimage comprueba que el modelo existe. Un error tipográfico o un coche addon faltante se detiene aquí en lugar de congelarse.
  2. RequestModel luego un bucle en HasModelLoaded espera, con un timeout.
  3. CreateVehicle toma el modelo, posición, heading, luego isNetwork (true para que otros jugadores lo vean) y netMissionEntity.
  4. SetModelAsNoLongerNeeded libera la memoria del modelo cuando hayas terminado.

Si el vehículo es un addon, mira cómo añadir coches addon primero. Un modelo que no se transmite nunca carga.

Consejo: con ox_lib, lib.requestModel(model) hace la solicitud y la espera por ti, y da error en un timeout.

Pon al jugador en el asiento del conductor y establece la matrícula:

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

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

La matrícula contiene como máximo 8 caracteres.

Desova en el servidor con CreateVehicleServerSetter

En OneSync, el servidor puede crear el vehículo a sí mismo. Esto es más confiable para scripts donde el servidor decide el desove, como un garaje o un vehículo de trabajo, y ningún cliente tiene que estar cerca:

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)

El segundo argumento es el tipo de vehículo como una cadena: 'automobile', 'bike', 'boat', 'heli', 'plane', 'submarine', 'trailer' o 'train'. Elige el que coincida con el modelo. Un motocicleta creada como un automóvil se comportará incorrectamente.

A diferencia del cliente, no solicitas el modelo en el servidor. La llamada también es asincrónica: la entidad puede no existir en el momento en que vuelve, así que espera a DoesEntityExist, con un timeout en código real.

Habilita OneSync en server.cfg, o la llamada no funciona. Mira cómo habilitar OneSync.

Net ids: entregando el coche a un cliente

Un vehículo creado en el servidor tiene un handle de entidad que solo existe en el servidor. Un cliente no puede usarlo. Para referenciar el coche entre máquinas, usa su network id, que es el mismo en todas partes:

lua
-- server
local netId = NetworkGetNetworkIdFromEntity(vehicle)

En el cliente, espera a que la entidad exista en esa máquina, luego convierte:

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)

Nunca envíes el handle de entidad cruda sobre un evento: no significa nada en otra máquina.

Matrículas y llaves

Establece la matrícula justo después de que exista el vehículo, como en los ejemplos anteriores, y antes de entregar las llaves. Las llaves dependen de tu script de llaves de vehículos, ya que cada script tiene su propia función. La mayoría funcionan con la matrícula, así que el orden habitual es:

  1. Crear el vehículo.
  2. Establecer la matrícula con SetVehicleNumberPlateText.
  3. Llamar la exportación o evento de tu script de llaves con esa matrícula.

Almacena la misma matrícula en tu base de datos, si el vehículo es propiedad, para que el garaje pueda encontrarlo de nuevo. Comprueba la documentación del script de llaves que usas para la llamada exacta. No copies una llamada de otro servidor.

Por qué los coches desovados desaparecen

No relevante para nadie. El juego elimina una entidad en red cuando nadie está cerca. Un coche desovado en el servidor para un jugador que luego se aleja puede ser eliminado.

El propietario se fue. Una entidad pertenece a un jugador que la posee. Cuando el propietario de un vehículo desovado por el cliente se desconecta o se aleja, puede ser eliminado. En el servidor puedes establecer qué sucede:

lua
SetEntityOrphanMode(vehicle, 2)

El modo huérfano 2 es "mantener la entidad", 0 es el por defecto (eliminar cuando no es relevante), y 1 la elimina cuando el propietario se desconecta. Comprueba la documentación nativa para tu construcción de servidor.

No marcado como una entidad de misión. En el cliente, la limpieza ambiental puede eliminar un coche que creaste. Márcalo para que el juego lo trate como tuyo:

lua
SetEntityAsMissionEntity(vehicle, true, true)

Un script de limpieza. Muchos servidores ejecutan un script que elimina vehículos desocupados. Si tus coches desaparecen en un tiempo fijo, esa es la causa, no tu código de desove.

Nunca se desovó. Un coche invisible o faltante a menudo significa que el modelo no se cargó, CreateVehicle devolvió 0 y el script continuó. Siempre comprueba el handle devuelto.

Elimina coches tú mismo cuando hayas terminado, con DeleteEntity(vehicle), para que no se acumulen.

Lista de comprobación

Síntoma Solución
CreateVehicle devuelve 0 RequestModel y espera a HasModelLoaded primero
Congelarse en un nombre de modelo malo Comprueba IsModelInCdimage antes de solicitar
Solo el desovador ve el coche Pasa isNetwork = true a CreateVehicle
CreateVehicleServerSetter no hace nada Habilita OneSync y espera a DoesEntityExist
El cliente obtiene un id de entidad inútil Envía el net id, luego usa NetToVeh en el cliente
El coche desaparece después Marca como entidad de misión, establece el modo huérfano, comprueba scripts de limpieza
El jugador no puede conducir su coche Da las llaves con tu script de llaves, usando la matrícula

Respuestas rápidas

¿Necesito OneSync para usar CreateVehicleServerSetter?

Sí. La creación de entidades del lado del servidor necesita OneSync habilitado. En un servidor sin él, desova el vehículo en el cliente con CreateVehicle.

¿Por qué desaparece mi coche desovado?

Un vehículo en red se elimina cuando ya no es relevante para nadie, o cuando su propietario se va, a menos que le digas al juego que lo mantenga. Márcalo como una entidad de misión en el cliente, o establece su modo huérfano en el servidor.

¿Cómo le doy al jugador las llaves?

Depende del script de llaves de vehículos que use tu servidor. La mayoría tiene una exportación o evento de cliente que toma la matrícula, así que llama eso después de establecer la matrícula.

Scripts que evitan este problema

Advanced BoostingBoosting de vehículos desde una tablet: contratos de clase D a S+, crews y cola en vivo.Ver script →Chameleon Paints82 pinturas camaleón que cambian de color, en un menú de un clic.Ver script →

Sigue leyendo