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:

lua
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:

lua
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:

lua
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 con GetEntityCoords(PlayerPedId()) mentre stai lì, o da uno strumento di coordinate.
  • size per un box è larghezza, lunghezza e altezza come un vec3, centrato su coords.
  • rotation gira 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:

lua
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 e onExit si eseguono una volta per ogni incrocio. Usali per notifiche, testo UI, caricamento o scaricamento di qualcosa.
  • inside si 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:

lua
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 onEnter e onExit piuttosto che inside.
  • Disattiva debug in 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 →

Continua a leggere