Spawnar um veículo no FiveM: CreateVehicle vs CreateVehicleServerSetter
Spawne veículos da forma certa no FiveM: CreateVehicle de cliente com RequestModel, CreateVehicleServerSetter de servidor no OneSync, net ids, placas, chaves e carros desaparecendo.
Você spawna um veículo e ele aparece invisível, spawna sob o mapa, desaparece após um minuto, ou apenas o jogador que o spawnou consegue vê-lo. Há duas formas corretas de spawnar um carro, e cada uma tem um conjunto diferente de armadilhas. Este artigo mostra ambas, como definir a placa e entregar as chaves, e por que os carros spawnados desaparecem.
Spawne no cliente com CreateVehicle
A versão de cliente é a que a maioria dos scripts usa. O modelo deve estar carregado antes de você criar o veículo, ou CreateVehicle retorna 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
endOs passos:
IsModelInCdimageverifica que o modelo existe. Um erro de digitação ou um carro addon faltando para aqui em vez de congelar.RequestModeldepois um loop emHasModelLoadedespera por ele, com um timeout.CreateVehicletoma o modelo, posição, heading, depoisisNetwork(truepara que outros jogadores vejam) enetMissionEntity.SetModelAsNoLongerNeededlibera a memória do modelo quando termina.
Se o veículo é um addon, veja como adicionar carros addon primeiro. Um modelo que não é streamed nunca carrega.
Dica: com ox_lib,
lib.requestModel(model)faz o pedido e a espera para você, e gera erro em um timeout.
Coloque o jogador no banco do motorista e defina a placa:
local vehicle = spawnVehicle('sultan', GetEntityCoords(PlayerPedId()), GetEntityHeading(PlayerPedId()))
if vehicle then
SetVehicleNumberPlateText(vehicle, 'MIC 001')
SetPedIntoVehicle(PlayerPedId(), vehicle, -1)
endA placa tem no máximo 8 caracteres.
Spawne no servidor com CreateVehicleServerSetter
No OneSync, o servidor pode criar o veículo em si. Isso é mais confiável para scripts onde o servidor decide o spawn, como uma garagem ou um veículo de job, e nenhum cliente precisa ficar perto:
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)O segundo argumento é o tipo de veículo como uma string: 'automobile', 'bike', 'boat', 'heli', 'plane', 'submarine', 'trailer' ou 'train'. Escolha o que corresponde ao modelo. Uma bicicleta criada como um automóvel se comportará de forma errada.
Ao contrário do cliente, você não requisita o modelo no servidor. A chamada também é assíncrona: a entidade pode não existir no momento em que retorna, então aguarde DoesEntityExist, com um timeout no código real.
Ative o OneSync no server.cfg, ou a chamada não funciona. Veja como ativar o OneSync.
Net ids: entregando o carro para um cliente
Um veículo criado no servidor tem um identificador de entidade que só existe no servidor. Um cliente não pode usá-lo. Para referenciar o carro entre máquinas, use seu network id, que é o mesmo em todos os lugares:
-- server
local netId = NetworkGetNetworkIdFromEntity(vehicle)No cliente, aguarde a entidade existir naquela máquina, depois converta:
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 envie o identificador de entidade bruto sobre um evento: não significa nada em outra máquina.
Placas e chaves
Defina a placa logo após o veículo existir, como nos exemplos acima, e antes de entregar as chaves. As chaves dependem do script de chaves de veículo que seu servidor usa, já que cada script tem sua própria função. A maioria funciona com a placa, então a ordem usual é:
- Crie o veículo.
- Defina a placa com
SetVehicleNumberPlateText. - Chame a exportação ou evento do seu script de chaves com aquela placa.
Armazene a mesma placa em seu banco de dados, se o veículo for proprietário, para que a garagem possa encontrá-lo novamente. Verifique a documentação do script de chaves que você usa para a chamada exata. Não copie uma chamada de outro servidor.
Por que os carros spawnados desaparecem
Não relevante para ninguém. O jogo remove uma entidade em rede quando ninguém está perto dela. Um carro spawnado no servidor para um jogador que se afasta pode ser deletado.
O proprietário saiu. Uma entidade pertence a um jogador que a possui. Quando o proprietário de um veículo spawnado no cliente desconecta ou se afasta, pode ser removido. No servidor você pode definir o que acontece:
SetEntityOrphanMode(vehicle, 2)O modo órfão 2 é "manter a entidade", 0 é o padrão (deletar quando não relevante), e 1 a deleta quando o proprietário desconecta. Verifique a documentação nativa para sua compilação de servidor.
Não marcada como uma entidade de missão. No cliente, a limpeza ambiente pode deletar um carro que você criou. Marque-o para que o jogo a trate como sua:
SetEntityAsMissionEntity(vehicle, true, true)Um script de limpeza. Muitos servidores executam um script que remove veículos desocupados. Se seus carros desaparecem em um horário fixo, essa é a causa, não seu código de spawn.
Nunca spawnou. Um carro invisível ou ausente geralmente significa que o modelo não foi carregado, CreateVehicle retornou 0 e o script continuou. Sempre verifique o identificador retornado.
Delete carros você mesmo quando terminar, com DeleteEntity(vehicle), para que não se acumulem.
Lista de verificação
| Sintoma | Solução |
|---|---|
CreateVehicle retorna 0 |
RequestModel e aguarde HasModelLoaded primeiro |
| Congelar em um nome de modelo ruim | Verifique IsModelInCdimage antes de requisitar |
| Apenas o spawner vê o carro | Passe isNetwork = true para CreateVehicle |
CreateVehicleServerSetter não faz nada |
Ative o OneSync e aguarde DoesEntityExist |
| Cliente recebe um id de entidade inútil | Envie o net id, depois use NetToVeh no cliente |
| Carro desaparece depois | Marque como entidade de missão, defina o modo órfão, verifique scripts de limpeza |
| Jogador não consegue dirigir seu carro | Dê as chaves com seu script de chaves, usando a placa |
Respostas rápidas
Preciso de OneSync para usar CreateVehicleServerSetter?
Sim. A criação de entidades do lado do servidor precisa de OneSync ativado. Em um servidor sem ele, spawne o veículo no cliente com CreateVehicle.
Por que meu carro spawnado desaparece?
Um veículo em rede é deletado quando não é mais relevante para ninguém, ou quando seu proprietário sai, a menos que você diga ao jogo para mantê-lo. Marque-o como uma entidade de missão no cliente, ou defina seu modo órfão no servidor.
Como dou as chaves para o jogador?
Depende do script de chaves de veículo que seu servidor usa. A maioria tem uma exportação ou evento de cliente que toma a placa, então chame-o após definir a placa.

