Спавн транспортного средства в FiveM: CreateVehicle vs CreateVehicleServerSetter
Спавньте транспортные средства правильно в FiveM: клиент CreateVehicle с RequestModel, сервер CreateVehicleServerSetter на OneSync, net ids, номерные знаки, ключи и исчезающие машины.
Вы спавните транспортное средство, и оно появляется невидимым, спавнится под картой, исчезает через минуту, или только игрок, который его спавнил, может его видеть. Есть два правильных способа спавнить машину, и каждый имеет свой набор подводных камней. Эта статья показывает оба, как установить номерной знак и передать ключи, и почему созданные машины исчезают.
Спавн на клиенте с CreateVehicle
Версия клиента - это то, что используют большинство скриптов. Модель должна быть загружена перед созданием транспортного средства, или CreateVehicle вернет 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
endШаги:
IsModelInCdimageпроверяет, что модель существует. Опечатка или отсутствующий дополнительный автомобиль останавливается здесь вместо зависания.RequestModelзатем цикл наHasModelLoadedждет его с тайм-аутом.CreateVehicleпринимает модель, позицию, направление, затемisNetwork(true, чтобы другие игроки видели его) иnetMissionEntity.SetModelAsNoLongerNeededосвобождает память модели, когда вы закончили.
Если транспортное средство - это дополнение, сначала смотрите how to add addon cars. Модель, которая не потоковая, никогда не загружается.
Совет: с ox_lib,
lib.requestModel(model)выполняет запрос и ожидание для вас и выдает ошибку при тайм-ауте.
Посадите игрока на водительское место и установите номерной знак:
local vehicle = spawnVehicle('sultan', GetEntityCoords(PlayerPedId()), GetEntityHeading(PlayerPedId()))
if vehicle then
SetVehicleNumberPlateText(vehicle, 'MIC 001')
SetPedIntoVehicle(PlayerPedId(), vehicle, -1)
endНомерной знак содержит максимум 8 символов.
Спавн на сервере с CreateVehicleServerSetter
На OneSync сервер может создать транспортное средство сам. Это более надежно для скриптов, где сервер решает спавн, таких как гараж или служебное транспортное средство, и ни один клиент не должен оставаться близко:
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)Второй аргумент - это тип транспортного средства как строка: 'automobile', 'bike', 'boat', 'heli', 'plane', 'submarine', 'trailer' или 'train'. Выберите тот, который соответствует модели. Мотоцикл, созданный как автомобиль, будет вести себя неправильно.
В отличие от клиента, вы не запрашиваете модель на сервере. Вызов также асинхронный: объект может не существовать в момент его возврата, поэтому ждите DoesEntityExist с тайм-аутом в реальном коде.
Включите OneSync в server.cfg или вызов не будет работать. Смотрите how to enable OneSync.
Net ids: передача машины клиенту
Транспортное средство, созданное на сервере, имеет дескриптор объекта, который существует только на сервере. Клиент не может его использовать. Чтобы ссылаться на автомобиль между машинами, используйте его network id, который одинаков везде:
-- server
local netId = NetworkGetNetworkIdFromEntity(vehicle)На клиенте дождитесь, пока объект существует на этой машине, затем преобразуйте:
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)Никогда не отправляйте необработанный дескриптор объекта через событие: это ничего не означает на другой машине.
Номерные знаки и ключи
Установите номерной знак сразу после существования транспортного средства, как в примерах выше, и перед передачей ключей. Ключи зависят от скрипта ключей транспортного средства вашего сервера, так как каждый скрипт имеет свою собственную функцию. Большинство работают с номерным знаком, поэтому обычный порядок:
- Создайте транспортное средство.
- Установите номерной знак с
SetVehicleNumberPlateText. - Вызовите экспорт или событие скрипта ключей с этим номерным знаком.
Сохраняйте один и тот же номерной знак в своей базе данных, если транспортное средство принадлежит, чтобы гараж мог его найти снова. Проверьте документацию скрипта ключей, который вы используете, для точного вызова. Не копируйте вызов с другого сервера.
Почему созданные машины исчезают
Не актуально для кого-либо. Игра удаляет сетевой объект, когда никто не находится рядом с ним. Машина, созданная на сервере для игрока, который затем уходит, может быть удалена.
Владелец ушел. Объект принадлежит игроку, который его владеет. Когда владелец созданного клиентом транспортного средства отключается или уходит, он может быть удален. На сервере вы можете установить, что происходит:
SetEntityOrphanMode(vehicle, 2)Режим сирот 2 - "сохранить объект", 0 - по умолчанию (удалить, когда не актуально), и 1 удаляет его, когда владелец отключается. Проверьте документацию встроенной функции для вашей сборки сервера.
Не отмечено как миссионный объект. На клиенте очистка окружающей среды может удалить машину, которую вы создали. Отметьте это, чтобы игра относилась к нему как к вашему:
SetEntityAsMissionEntity(vehicle, true, true)Скрипт очистки. Многие серверы запускают скрипт, который удаляет незанятые транспортные средства. Если ваши машины исчезают в установленное время, это причина, а не ваш код спавна.
Он никогда не спавнился. Невидимая или отсутствующая машина часто означает, что модель не была загружена, CreateVehicle вернул 0 и скрипт продолжил. Всегда проверяйте возвращаемый дескриптор.
Удалите машины сами, когда вы закончили, с DeleteEntity(vehicle), чтобы они не накапливались.
Контрольный список
| Симптом | Решение |
|---|---|
CreateVehicle возвращает 0 |
RequestModel и дождитесь HasModelLoaded сначала |
| Зависание на плохом имени модели | Проверьте IsModelInCdimage перед запросом |
| Только спавнер видит машину | Передайте isNetwork = true в CreateVehicle |
CreateVehicleServerSetter ничего не делает |
Включите OneSync и ждите DoesEntityExist |
| Клиент получает бесполезный id объекта | Отправьте net id, затем используйте NetToVeh на клиенте |
| Машина исчезает позже | Отметьте как миссионный объект, установите режим сирот, проверьте скрипты очистки |
| Игрок не может водить свою машину | Дайте ключи со скриптом ключей, используя номерной знак |
Короткие ответы
Нужен ли мне OneSync для использования CreateVehicleServerSetter?
Да. Создание объектов на стороне сервера требует включенного OneSync. На сервере без него спавньте транспортное средство на клиенте с CreateVehicle.
Почему моя созданная машина исчезает?
Сетевое транспортное средство удаляется, когда оно больше не актуально для кого-либо, или когда его владелец уходит, если вы не скажете игре его сохранить. Отметьте его как миссионный объект на клиенте или установите режим сирот на сервере.
Как мне дать игроку ключи?
Это зависит от скрипта ключей транспортного средства, который использует ваш сервер. Большинство имеют экспорт на клиенте или событие, которое принимает номерной знак, поэтому вызовите это после установки номерного знака.

