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 :
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 :
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 :
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
coordsest le centre d'une box ou d'une sphere. Obtenez-le avecGetEntityCoords(PlayerPedId())en vous tenant là-bas, ou à partir d'un outil de coordonnées.sizepour une box est la largeur, la longueur et la hauteur en tant quevec3, centrées surcoords.rotationtourne la box autour de son axe vertical, en degrés. Utilisez le heading du bâtiment ou de la porte.radiusest 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 :
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,
})onEnteretonExits'exécutent une fois par franchissement. Utilisez-les pour les notifications, l'interface utilisateur textuelle, le chargement ou le déchargement de quelque chose.insides'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 :
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
onEnteretonExitplutôt queinside. - Désactivez
debugen 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 →