Zones ox_lib : lib.zones.box, sphere et poly avec onEnter et onExit

Comment utiliser les zones ox_lib dans FiveM : lib.zones.box, sphere et poly avec coords, size, rotation et debug, onEnter, onExit, inside, suppression des zones, et ox_target.

Vous devez savoir quand un joueur entre dans un magasin, un garage ou une zone restreinte, sans vérifier la distance dans une boucle chaque image. Les zones ox_lib le font pour vous : vous décrivez une forme, et elle appelle votre fonction quand le joueur entre ou sort. Ce guide couvre les trois formes, les rappels, la suppression et quand utiliser ox_target à la place.

Les zones ont besoin d'ox_lib comme dépendance, chargées avec @ox_lib/init.lua. Si elle est manquante, voir ox_lib init.lua not found.

Types de zones

Il y en a trois, tous sous lib.zones et tous côté client.

Box, un rectangle avec une hauteur, bon pour les pièces et les portes :

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 rayon autour d'un point, bon pour les zones ouvertes :

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 contour de points pour les formes irrégulières comme une cour ou un parking :

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,
})

Pour une poly, thickness est à quelle hauteur la forme s'étend autour de la hauteur des points. Gardez les points au niveau du sol et la thickness assez grande pour inclure les joueurs sur les escaliers.

Coords, size et rotation

  • coords est le centre d'une box ou d'une sphere. Obtenez-le avec GetEntityCoords(PlayerPedId()) en vous tenant là-bas, ou à partir d'un outil de coordonnées.
  • size pour une box est la largeur, la longueur et la hauteur en tant que vec3, centrées sur coords.
  • rotation tourne la box autour de son axe vertical, en degrés. Utilisez le heading du bâtiment ou de la porte.
  • radius est pour les spheres.

Le moyen le plus facile de les obtenir correctement est debug = true : la zone est dessinée dans le monde, afin que vous puissiez la traverser, changer un nombre et redémarrer la ressource jusqu'à ce qu'elle s'ajuste. Désactivez le debug avant release, car il dessine chaque image.

Rappels : onEnter, onExit, inside

Trois rappels couvrent les cas :

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 et onExit s'exécutent une fois par franchissement. Utilisez-les pour les notifications, l'interface utilisateur textuelle, le chargement ou le déchargement de quelque chose.
  • inside s'exécute à chaque tick tandis que le joueur est à l'intérieur. Tout ce qui doit être vérifié à chaque image, comme une pression de touche, va ici, et rien en dehors de la zone ne vous coûte.

Gardez inside court : pas d'appels de base de données, pas de lib.callback.await, pas de Wait dans une boucle. Pour le détail de la pression de touche, voir markers and text UI.

Suppression de zones

lib.zones.box retourne un objet. Gardez-le et supprimez-le quand la zone cesse d'importer :

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)

N'oubliez pas de masquer toute interface utilisateur que la zone affichait : si le joueur est à l'intérieur quand vous la supprimez, onExit peut ne pas être appelé pour lui.

Vous pouvez également demander à une zone si un point est à l'intérieur, avec zone:contains(coords), par exemple pour vérifier la position du joueur quand un menu s'ouvre.

Zones vs ox_target

Ils résolvent différents problèmes :

lib.zones ox_target
Question « Le joueur est-il dans cette zone ? » « Le joueur regarde-t-il ceci et appuie-t-il sur un bouton ? »
Sortie Vos rappels Une liste d'options dans le menu cible
Utiliser pour Zones sûres, limites de vitesse, zones musicales, génération d'NPCs quand on est près Portes, guichets automatiques, comptoirs de magasin, objets

Si le joueur doit choisir d'interagir, utilisez ox_target zones, et comparez-le avec les anciens systèmes dans qb-target vs ox-target. Si quelque chose devrait se passer automatiquement quand ils arrivent, utilisez une zone lib. Les combiner est courant : une zone charge un ped quand vous arrivez, et ox_target donne au ped ses options.

Performance

Les zones sont bon marché par rapport à une boucle manuelle #(coords - playerCoords) < 3.0, car ox_lib les vérifie dans une boucle centrale unique et n'exécute votre fonction inside que là où elle s'applique. Quelques habitudes le gardent ainsi :

  • Créez des zones une fois, pas dans une boucle ou chaque fois qu'un menu s'ouvre.
  • Ne créez pas des centaines de petites zones si une plus grande en ferait l'affaire.
  • Mettez le travail dans onEnter et onExit plutôt que inside.
  • Désactivez debug en production.

Vérifiez le résultat avec resmon, comme dans high resmon ms.

Liste de contrôle

Symptôme Correction
La zone ne se déclenche jamais Utilisez les coords du centre, la bonne size et rotation ; définissez debug = true pour la voir
lib est nil Ajouter @ox_lib/init.lua à shared_scripts
L'interface utilisateur textuelle reste après le départ Appeler lib.hideTextUI() dans onExit et quand la zone est supprimée
La pression de touche ne s'est pas détectée La vérifier dans inside, pas onEnter
Le redémarrage de la ressource laisse les zones derrière Appeler zone:remove() sur onResourceStop
Resmon élevé Garder inside léger et désactiver debug

Réponses rapides

Quelle est la différence entre lib.zones et ox_target ?

lib.zones vous dit quand le joueur est dans une zone, afin que vous exécutiez votre propre code. ox_target ajoute une interaction (une option d'observation et de clic) à une entité ou une zone. Utilisez les zones pour les zones, ox_target pour les choses sur lesquelles le joueur appuie.

Comment montrer une zone pendant que je la construis ?

Définissez debug = true dans les options de la zone. Elle dessine la forme dans le monde, afin que vous puissiez corriger les coordonnées, la taille et la rotation. Désactivez-le quand vous avez terminé.

Comment supprimer une zone ?

Gardez l'objet que lib.zones.box retourne et appelez zone:remove(). Faites-le quand la ressource s'arrête ou quand la zone n'est plus nécessaire.

Des scripts sans ce problème

Shop CreatorCréez un magasin en moins d’une minute — propriétaires, employés, coffres et braquages inclus.Voir le script →Advanced BoostingDu boosting de véhicules piloté par tablette : contrats de classe D à S+, crews et file d’attente en direct.Voir le script →CCTV Security CamerasDes caméras à placer, une tablette multi-vues en direct et des photos imprimées comme preuves.Voir le script →

À lire aussi