Zone ox_lib: lib.zones.box, sphere e poly con onEnter e onExit
Come usare le zone ox_lib in FiveM: lib.zones.box, sphere e poly con coords, size, rotation e debug, onEnter, onExit, inside, rimozione di zone, e ox_target.
Hai bisogno di sapere quando un giocatore entra in un negozio, un garage o un'area ristretta, senza controllare la distanza in un ciclo ogni fotogramma. Le zone ox_lib lo fanno per te: descrivi una forma, e chiama la tua funzione quando il giocatore entra o esce. Questa guida copre le tre forme, i callback, la rimozione e quando usare ox_target.
Le zone hanno bisogno di ox_lib come dipendenza, caricata con @ox_lib/init.lua. Se manca, vedi ox_lib init.lua not found.
Tipi di zona
Ce ne sono tre, tutti sotto lib.zones e tutti lato client.
Box, un rettangolo con un'altezza, buono per stanze e porte:
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 raggio intorno a un punto, buono per aree aperte:
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 di punti per forme irregolari come un cortile o un parcheggio:
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,
})Per un poly, thickness è quanto alta è la forma intorno all'altezza dei punti. Mantieni i punti a livello del suolo e lo spessore abbastanza grande da includere i giocatori sulle scale.
Coords, size e rotation
coordsè il centro di un box o sphere. Ottenilo conGetEntityCoords(PlayerPedId())mentre stai lì, o da uno strumento di coordinate.sizeper un box è larghezza, lunghezza e altezza come unvec3, centrato sucoords.rotationgira il box intorno al suo asse verticale, in gradi. Usa l'intestazione dell'edificio o della porta.radiusè per le sphere.
Il modo più facile per farli funzionare è debug = true: la zona è disegnata nel mondo, così puoi camminarci attraverso, cambiare un numero e riavviare la risorsa finché non si adatta. Disattiva il debug prima del rilascio, poiché disegna ogni fotogramma.
Callback: onEnter, onExit, inside
Tre callback coprono i casi:
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,
})onEntereonExitsi eseguono una volta per ogni incrocio. Usali per notifiche, testo UI, caricamento o scaricamento di qualcosa.insidesi esegue ogni tick mentre il giocatore è dentro. Qualsiasi cosa che deve essere controllata ogni fotogramma, come una pressione di tasto, va qui, e nulla al di fuori della zona ti costa.
Mantieni inside breve: nessuna chiamata al database, nessun lib.callback.await, nessun Wait in un ciclo. Per il dettaglio della pressione di tasto, vedi marcatori e testo UI.
Rimozione di zone
lib.zones.box restituisce un oggetto. Tienilo e rimuovilo quando l'area non ha più importanza:
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)Ricorda di nascondere qualsiasi testo UI che la zona stava mostrando: se il giocatore è dentro quando la rimuovi, onExit potrebbe non essere chiamato per loro.
Puoi anche chiedere a una zona se un punto è dentro di essa, con zone:contains(coords), ad esempio per controllare la posizione del giocatore quando un menu si apre.
Zone vs ox_target
Risolvono problemi diversi:
| lib.zones | ox_target | |
|---|---|---|
| Domanda | "Il giocatore è in questa area?" | "Il giocatore sta guardando questo e premendo un pulsante?" |
| Output | I tuoi callback | Un elenco di opzioni nel menu di destinazione |
| Usare per | Zone sicure, limiti di velocità, aree musicali, spawnare NPC quando vicino | Porte, bancomat, banconi del negozio, oggetti |
Se il giocatore dovrebbe scegliere di interagire, usa zone ox_target, e confrontalo con i sistemi precedenti in qb-target vs ox-target. Se qualcosa dovrebbe accadere automaticamente quando arrivano, usa una zona lib. Combinarli è comune: una zona carica un ped quando arrivi, e ox_target dà al ped le sue opzioni.
Performance
Le zone sono economiche rispetto a un ciclo manuale #(coords - playerCoords) < 3.0, perché ox_lib le controlla in un ciclo centrale e esegue solo la tua funzione inside dove si applica. Poche abitudini lo mantengono così:
- Crea le zone una volta, non in un ciclo o ogni volta che un menu si apre.
- Non creare centinaia di piccole zone se una sola più grande farebbe.
- Metti il lavoro in
onEntereonExitpiuttosto cheinside. - Disattiva
debugin produzione.
Controlla il risultato con resmon, come in resmon ms alto.
Checklist
| Sintomo | Soluzione |
|---|---|
| La zona non si attiva mai | Usa le coords centrali, la size e la rotation giuste; imposta debug = true per vederla |
lib è nil |
Aggiungi @ox_lib/init.lua a shared_scripts |
| Il testo UI rimane dopo aver lasciato | Chiama lib.hideTextUI() in onExit e quando la zona viene rimossa |
| La pressione del tasto non rilevata | Controllala in inside, non onEnter |
| Il riavvio della risorsa lascia zone dietro | Chiama zone:remove() su onResourceStop |
| Resmon alto | Mantieni inside leggero e disabilita debug |
Risposte rapide
Qual è la differenza tra lib.zones e ox_target?
lib.zones ti dice quando il giocatore è dentro un'area, così esegui il tuo codice. ox_target aggiunge un'interazione (un'opzione di sguardo e clic) a un'entità o una zona. Usa le zone per le aree, ox_target per le cose che il giocatore preme.
Come mostro una zona mentre la sto costruendo?
Imposta debug = true nelle opzioni della zona. Disegna la forma nel mondo, così puoi correggere le coordinate, la dimensione e la rotazione. Disattivalo quando hai finito.
Come rimuovo una zona?
Tieni l'oggetto che lib.zones.box restituisce e chiama zone:remove(). Fallo quando la risorsa si ferma o quando l'area non è più necessaria.
Script senza questo problema
Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →
Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →
CCTV Security CamerasTelecamere posizionabili, un tablet multi-vista in diretta e foto stampate come prove.Vedi script →