Зоны ox_lib: lib.zones.box, sphere и poly с onEnter и onExit
Как использовать зоны ox_lib в FiveM: lib.zones.box, sphere и poly с координатами, размером, поворотом и отладкой, onEnter, onExit, inside, удаление зон и ox_target.
Вам нужно знать, когда игрок входит в магазин, гараж или запретную зону, без проверки расстояния в цикле каждый кадр. Зоны ox_lib это делают для вас: вы описываете фигуру, и она вызывает вашу функцию, когда игрок входит или выходит. Это руководство охватывает три фигуры, обратные вызовы, удаление и когда использовать ox_target.
Зоны нуждаются в ox_lib как зависимости, загруженной с @ox_lib/init.lua. Если она отсутствует, смотрите ox_lib init.lua not found.
Типы зон
Есть три, все под lib.zones и все на стороне клиента.
Box, прямоугольник с высотой, хорош для комнат и дверных проёмов:
local zone = lib.zones.box({
coords = vec3(441.0, -981.0, 30.7),
size = vec3(4.0, 6.0, 3.0),
rotation = 90.0,
debug = true,
onEnter = function(self)
print('entered the box')
end,
onExit = function(self)
print('left the box')
end,
})Sphere, радиус вокруг точки, хорош для открытых площадей:
local zone = lib.zones.sphere({
coords = vec3(441.0, -981.0, 30.7),
radius = 3.0,
debug = true,
onEnter = function() print('in range') end,
onExit = function() print('out of range') end,
})Poly, контур точек для неправильных форм, таких как двор или парковка:
local zone = lib.zones.poly({
points = {
vec3(400.0, -1000.0, 29.0),
vec3(420.0, -1000.0, 29.0),
vec3(420.0, -970.0, 29.0),
vec3(400.0, -970.0, 29.0),
},
thickness = 4.0,
debug = true,
onEnter = function() print('in the yard') end,
onExit = function() print('left the yard') end,
})Для poly, thickness — это высота фигуры вокруг высоты точек. Держите точки на уровне земли и толщину достаточно большой, чтобы включить игроков на лестницах.
Координаты, размер и поворот
coords— это центр коробки или сферы. Получите его сGetEntityCoords(PlayerPedId())при стоянии там, или из инструмента координат.sizeдля коробки — это ширина, длина и высота какvec3, центрированные наcoords.rotationповорачивает коробку вокруг её вертикальной оси в градусах. Используйте направление здания или двери.radiusпредназначен для сфер.
Самый простой способ получить это правильно — debug = true: зона рисуется в мире, поэтому вы можете пройти сквозь неё, изменить число и перезагрузить ресурс, пока она не подойдёт. Выключите отладку перед выпуском, так как она рисует каждый кадр.
Обратные вызовы: onEnter, onExit, inside
Три обратных вызова охватывают случаи:
local zone = lib.zones.sphere({
coords = vec3(441.0, -981.0, 30.7),
radius = 4.0,
onEnter = function(self)
lib.showTextUI('[E] Open shop')
end,
onExit = function(self)
lib.hideTextUI()
end,
inside = function(self)
if IsControlJustReleased(0, 38) then
print('pressed E inside the zone')
end
end,
})onEnterиonExitзапускаются один раз за пересечение. Используйте их для уведомлений, текстового пользовательского интерфейса, загрузки или выгрузки чего-то.insideзапускается каждый тик пока игрок внутри. Всё, что должно быть проверено каждый кадр, как нажатие клавиши, идёт сюда, и ничто вне зоны вас не стоит.
Держите inside коротким: никаких вызовов базы данных, никаких lib.callback.await, никаких Wait в цикле. Для деталей нажатия клавиши смотрите маркеры и текстовый пользовательский интерфейс.
Удаление зон
lib.zones.box возвращает объект. Сохраняйте его и удаляйте, когда область больше не имеет значения:
local shopZone
local function createZone()
shopZone = lib.zones.box({
coords = vec3(441.0, -981.0, 30.7),
size = vec3(4.0, 4.0, 3.0),
onEnter = function() lib.showTextUI('[E] Shop') end,
onExit = function() lib.hideTextUI() end,
})
end
local function removeZone()
if shopZone then
shopZone:remove()
shopZone = nil
end
end
AddEventHandler('onResourceStop', function(resource)
if resource == GetCurrentResourceName() then
removeZone()
lib.hideTextUI()
end
end)Помните скрыть любой пользовательский интерфейс, который показывала зона: если игрок внутри, когда вы её удаляете, onExit может не быть вызван для них.
Вы также можете спросить зону, находится ли точка внутри неё, с zone:contains(coords), например, чтобы проверить позицию игрока при открытии меню.
Зоны vs ox_target
Они решают разные проблемы:
| lib.zones | ox_target | |
|---|---|---|
| Вопрос | "Находится ли игрок в этой области?" | "Смотрит ли игрок на это и нажимает кнопку?" |
| Результат | Ваши обратные вызовы | Список опций в меню цели |
| Используйте для | Безопасные зоны, ограничения скорости, музыкальные области, спавнинг NPC-ов при близости | Двери, банкоматы, прилавки магазинов, объекты |
Если игрок должен выбрать взаимодействие, используйте зоны ox_target и сравните с более старыми системами в qb-target vs ox-target. Если что-то должно происходить автоматически при прибытии, используйте зону lib. Их комбинирование часто встречается: зона загружает ped при прибытии и ox_target даёт ped его опции.
Производительность
Зоны дёшевы по сравнению с ручным циклом #(coords - playerCoords) < 3.0, потому что ox_lib проверяет их в одном центральном цикле и только запускает вашу функцию inside, где это применимо. Несколько привычек держат это так:
- Создавайте зоны один раз, не в цикле или каждый раз, когда открывается меню.
- Не создавайте сотни крошечных зон, если одна больше подойдёт.
- Поместите работу в
onEnterиonExitвместоinside. - Выключите
debugв production.
Проверьте результат с resmon, как в high resmon ms.
Контрольный список
| Симптом | Решение |
|---|---|
| Зона никогда не срабатывает | Используйте центр coords, правильный size и rotation; установите debug = true чтобы видеть |
lib равен nil |
Добавьте @ox_lib/init.lua в shared_scripts |
| Текстовый пользовательский интерфейс остаётся после выхода | Вызовите lib.hideTextUI() в onExit и когда зона удаляется |
| Нажатие клавиши не обнаруживается | Проверьте это в inside, а не в onEnter |
| Перезагрузка ресурса оставляет зоны позади | Вызовите zone:remove() на onResourceStop |
| Высокий resmon | Держите inside лёгким и отключите debug |
Короткие ответы
В чём разница между lib.zones и ox_target?
lib.zones говорит вам, когда игрок находится внутри области, поэтому вы запускаете собственный код. ox_target добавляет взаимодействие (опцию посмотреть и щёлкнуть) на сущность или зону. Используйте зоны для областей, ox_target для вещей, которые игрок нажимает.
Как показать зону во время её построения?
Установите debug = true в параметрах зоны. Это рисует фигуру в мире, поэтому вы можете исправить координаты, размер и поворот. Выключите это, когда закончите.
Как удалить зону?
Сохраняйте объект, который возвращает lib.zones.box и вызовите zone:remove(). Сделайте это, когда ресурс останавливается или когда область больше не нужна.
Скрипты без этой проблемы
Shop CreatorМагазин меньше чем за минуту — владельцы, сотрудники, сейфы и ограбления в комплекте.Смотреть скрипт →
Advanced BoostingУгон машин на заказ через планшет: контракты от класса D до S+, команды и живая очередь.Смотреть скрипт →
CCTV Security CamerasУстанавливаемые камеры, планшет с мультиэкраном в реальном времени и распечатанные фото-улики.Смотреть скрипт →