Zonas de ox_lib: lib.zones.box, sphere y poly con onEnter y onExit
Cómo usar zonas de ox_lib en FiveM: lib.zones.box, sphere y poly con coords, tamaño, rotación y debug, onEnter, onExit, inside, eliminando zonas, y ox_target.
Necesitas saber cuándo un jugador entra en una tienda, un garaje o un área restringida, sin verificar la distancia en un bucle cada fotograma. Las zonas de ox_lib lo hacen por ti: describes una forma, y llama tu función cuando el jugador entra o sale. Esta guía cubre las tres formas, los callbacks, eliminación y cuándo usar ox_target en su lugar.
Las zonas necesitan ox_lib como dependencia, cargada con @ox_lib/init.lua. Si falta, véase ox_lib init.lua not found.
Tipos de zona
Hay tres, todas bajo lib.zones y todas del lado del cliente.
Box, un rectángulo con altura, bueno para habitaciones y puertas:
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, un radio alrededor de un punto, bueno para áreas abiertas:
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, un contorno de puntos para formas irregulares como un patio o un estacionamiento:
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,
})Para un poly, thickness es qué tan alta es la forma alrededor de la altura de los puntos. Mantén los puntos al nivel del suelo y el grosor lo suficientemente grande como para incluir jugadores en escaleras.
Coords, tamaño y rotación
coordses el centro de una caja o esfera. Obtén conGetEntityCoords(PlayerPedId())mientras estás de pie allí, o desde una herramienta de coordenadas.sizepara una caja es ancho, largo y alto como unvec3, centrado encoords.rotationgira la caja alrededor de su eje vertical, en grados. Usa el encabezado del edificio o puerta.radiuses para esferas.
La forma más fácil de acertar debug = true: la zona se dibuja en el mundo, para que puedas caminar a través de ella, cambiar un número e reiniciar el recurso hasta que encaje. Apaga debug antes del lanzamiento, ya que dibuja cada fotograma.
Callbacks: onEnter, onExit, inside
Tres callbacks cubren los casos:
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,
})onEnteryonExitse ejecutan una vez por cruce. Úsalos para notificaciones, UI de texto, cargando o descargando algo.insidese ejecuta cada tick mientras el jugador está dentro. Cualquier cosa que deba verificarse cada fotograma, como una pulsación de tecla, va aquí, y nada fuera de la zona te cuesta.
Mantén inside corto: sin llamadas a base de datos, sin lib.callback.await, sin Wait en un bucle. Para el detalle de pulsación de tecla, véase markers and text UI.
Eliminando zonas
lib.zones.box devuelve un objeto. Mantenlo y elimínalo cuando el área deje de importar:
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)Recuerda ocultar cualquier UI que la zona estaba mostrando: si el jugador está adentro cuando la eliminas, onExit puede no ser llamado para ellos.
También puedes preguntarle a una zona si un punto está dentro de ella, con zone:contains(coords), por ejemplo para verificar la posición del jugador cuando se abre un menú.
Zonas vs ox_target
Resuelven diferentes problemas:
| lib.zones | ox_target | |
|---|---|---|
| Pregunta | "¿Está el jugador en esta área?" | "¿Está el jugador mirando esto y presionando un botón?" |
| Salida | Tus callbacks | Una lista de opciones en el menú de objetivo |
| Usar para | Zonas seguras, límites de velocidad, áreas de música, generando NPCs cuando está cerca | Puertas, cajeros automáticos, mostradores de tienda, objetos |
Si el jugador debe elegir interactuar, usa ox_target zones, y compáralo con sistemas más antiguos en qb-target vs ox-target. Si algo debe suceder automáticamente cuando llegan, usa una zona lib. Combinarlos es común: una zona carga un ped cuando llegas, y ox_target le da opciones al ped.
Rendimiento
Las zonas son baratas en comparación con un bucle manual #(coords - playerCoords) < 3.0, porque ox_lib las verifica en un bucle central y solo ejecuta tu función inside donde aplica. Algunos hábitos lo mantienen de esa manera:
- Crea zonas una vez, no en un bucle o cada vez que se abre un menú.
- No crees cientos de zonas diminutas si una más grande sería suficiente.
- Pon el trabajo en
onEnteryonExiten lugar deinside. - Apaga
debugen producción.
Verifica el resultado con resmon, como en high resmon ms.
Lista de verificación
| Síntoma | Solución |
|---|---|
| La zona nunca se dispara | Usa el centro coords, el size y rotation correcto; establece debug = true para verla |
lib es nil |
Añade @ox_lib/init.lua a shared_scripts |
| La UI de texto permanece después de dejar | Llama a lib.hideTextUI() en onExit y cuando se elimina la zona |
| La pulsación de tecla no se detecta | Veríficala en inside, no en onEnter |
| El reinicio del recurso deja zonas atrás | Llama a zone:remove() en onResourceStop |
| Alto resmon | Mantén inside ligero y deshabilita debug |
Respuestas rápidas
¿Cuál es la diferencia entre lib.zones y ox_target?
lib.zones te dice cuándo el jugador está dentro de un área, así que ejecutas tu propio código. ox_target añade una interacción (una opción de mirar y hacer clic) a una entidad o zona. Usa zonas para áreas, ox_target para cosas que el jugador presiona.
¿Cómo muestro una zona mientras la construyo?
Establece debug = true en las opciones de zona. Dibuja la forma en el mundo, para que puedas corregir coordenadas, tamaño y rotación. Apágalo cuando termines.
¿Cómo elimino una zona?
Mantén el objeto que devuelve lib.zones.box y llama a zone:remove(). Hazlo cuando se detiene el recurso o cuando el área ya no es necesaria.
Scripts que evitan este problema
Shop CreatorCrea una tienda en menos de un minuto — dueños, empleados, caja fuerte y atracos.Ver script →
Advanced BoostingBoosting de vehículos desde una tablet: contratos de clase D a S+, crews y cola en vivo.Ver script →
CCTV Security CamerasCámaras colocables, una tablet con vista múltiple en vivo y fotos como prueba.Ver script →