OverflowOverflow
UI Library

Progress

A timed action. Blocking: it returns true if the player saw it through and false if it was cancelled or interrupted, so call it from a thread.

Beyond the visual it also handles the animation, attached props, disabled controls and the interruption rules for the duration of the action.

A progress bar labelled "Repairing engine"

progressBar

local completed = exports.of_ui:progressBar(data)

progressCircle

local completed = exports.of_ui:progressCircle(data)

A circular progress indicator labelled "Repairing"

The same options, drawn as a circle. position and percent apply only here.

FieldTypeDescription
durationnumberMilliseconds. Required.
labelstring?Text on the bar.
positionstring?middle or bottom. Circle only.
percentboolean?Show the percentage inside the circle. Circle only.
canCancelboolean?Lets the player cancel with the cancel key.
animtable?Animation to play. See below.
proptable?Prop(s) to attach. See below.
disabletable?{ move?, sprint?, car?, combat?, mouse? }: controls suppressed for the duration.
useWhileDeadboolean?Keep going if the player dies.
allowRagdollboolean?Keep going while ragdolled.
allowCuffedboolean?Keep going while cuffed.
allowFallingboolean?Keep going while falling.
allowSwimmingboolean?Keep going while swimming.

Returns true when it ran to completion, false when cancelled or interrupted, nil when it never started (the player was already in a state the options do not allow).

CreateThread(function()
    local completed = exports.of_ui:progressBar({
        label = 'Repairing engine',
        duration = 8000,
        canCancel = true,
        disable = { move = true, combat = true },
        anim = { dict = 'mini@repair', clip = 'fixing_a_ped' },
        prop = { model = 'prop_tool_wrench', bone = 28422,
                 pos = vec3(0.0, 0.0, 0.0), rot = vec3(0.0, 0.0, 0.0) },
    })

    if not completed then
        exports.of_ui:notify({ type = 'error', title = 'Repair cancelled' })
        return
    end

    TriggerServerEvent('vehicle:repaired')
end)

Interruption

By default the action stops if the player dies, ragdolls, gets cuffed, starts falling or starts swimming. Each allow* flag opts out of one of those checks.

The same checks run before the bar appears: a call that would immediately be interrupted returns nil without showing anything.

anim

FieldTypeDescription
dictstring?Animation dictionary.
clipstring?Clip inside the dictionary.
scenariostring?Scenario name, instead of dict/clip.
playEnterboolean?Play the scenario's enter animation. Default true.
blendIn / blendOutnumber?Blend speeds. Default 3.0 / 1.0.
durationnumber?Animation length. Defaults to the action's.
flagnumber?Animation flags. Default 49.
playbackRatenumber?Playback speed.
lockX / lockY / lockZboolean?Lock movement on that axis.

The animation stops when the action ends, whether it completed or not.

prop

One prop, or an array of them:

FieldTypeDescription
modelstringObject model.
bonenumber?Ped bone to attach to. Default 60309 (right hand).
posvector3Offset from the bone.
rotvector3Rotation.
rotOrdernumber?Rotation order.

Props are replicated to nearby players, so everyone sees the wrench, not just the person holding it. They are deleted when the action ends or the player disconnects.

Models larger than 2.5 units on any axis are rejected, as are peds and vehicles. The limit on simultaneous props comes from the ox:progressPropLimit convar (default 2).

cancelProgress

exports.of_ui:cancelProgress()

Cancels the running action from code. The waiting call returns false.

progressActive

local active = exports.of_ui:progressActive()

Whether an action is running.

Notes

  • Calls queue. A second progressBar waits for the first to finish rather than replacing it.
  • canCancel uses a keybind the player can rebind, X by default, listed in the FiveM keybind settings.
  • invBusy is set for the duration and restored after, so inventory scripts treat the player as occupied.
  • anim and prop need ox_lib: it is what loads models and animation dictionaries. The bar itself works without it.

On this page