Explorer
KNOW-PAT-088

FiveM - Dynamic Zone System avec lib.zones : spheres, boxes, polyzones

Domaine
fivem
Type
pattern
Priorité
P2

Parent : [[INDEX-FIVEM-GAMEPLAY]]

FiveM - Dynamic Zone System avec lib.zones : spheres, boxes, polyzones

Problème

Créer des zones d'interaction (pêche, farming, crafting) manuellement avec des threads et des checks de distance est répétitif, inefficace, et difficile à maintenir.

Solution

Utiliser lib.zones (ox_lib) pour créer des zones sphériques, box ou poly avec callbacks onEnter/onExit, déblocage progressif par niveau, et intégration avec ox_target.

-- Zone sphérique avec callbacks
local currentZone = nil

lib.zones.sphere({
    coords = vector3(-1800.0, -1200.0, 10.0),
    radius = 50.0,
    debug = Config.Debug,
    onEnter = function()
        currentZone = { index = 1, locationIndex = 1 }
        ShowNotification('Zone de pêche', 'success')
        -- Activer ox_target options
        exports.ox_target:addSphereZone({
            coords = vector3(-1800.0, -1200.0, 10.0),
            radius = 1.5,
            options = {
                {
                    name = 'fish_zone',
                    icon = 'fa-solid fa-fish',
                    label = 'Pêcher',
                    onSelect = function() StartFishing() end
                }
            }
        })
    end,
    onExit = function()
        currentZone = nil
        ShowNotification('Vous quittez la zone', 'inform')
        exports.ox_target:removeZone('fish_zone')
    end,
    inside = function()
        -- Appelé chaque frame si le joueur est dans la zone
        DrawMarker(1, -1800.0, -1200.0, 10.0, 0, 0, 0, 0, 0, 0, 2.0, 2.0, 1.0, 0, 150, 255, 100, false, false, 2, false, nil, nil, false)
    end
})

Pourquoi

  • lib.zones gère nativement l'entrée/sortie sans thread custom
  • Déblocage progressif par niveau/XP possible
  • Compatible ox_target pour les interactions contextuelles
  • Debug mode intégré pour visualiser les zones

Quand l'utiliser

  • Zones de farming, pêche, minage
  • Intérieurs de bâtiments avec comportement spécifique
  • Safe zones, zones PvP, zones de crafting

Quand NE PAS l'utiliser

  • Zone unique statique (overkill)
  • Si ox_lib n'est pas disponible sur le serveur

Exemples

Correct

-- Array de zones avec niveau requis
for i, zoneData in ipairs(Config.FishingZones) do
    lib.zones.sphere({
        coords = zoneData.coords,
        radius = zoneData.radius,
        onEnter = function()
            if PlayerLevel < zoneData.requiredLevel then
                ShowNotification('Niveau insuffisant', 'error')
                return
            end
            CurrentFishingZone = i
        end
    })
end

Incorrect

-- Thread custom avec distance check (CPU waste)
CreateThread(function()
    while true do
        Wait(1000)
        local ped = PlayerPedId()
        local coords = GetEntityCoords(ped)
        for _, zone in ipairs(Zones) do
            local dist = #(coords - zone.coords)
            if dist < zone.radius then
                if not InZone then
                    InZone = true
                    -- logic
                end
            else
                InZone = false
            end
        end
    end
end)

Références

  • lunar_fishing/client/main.lua L42-80
  • ox_target/client/api.lua L44-80
  • REF-003 (overextended ox_lib documentation)