Menu items
How to build the STG Radial Menu, from entry options, submenus, job and vehicle filters to the clothing and door actions and the addRadialItem and removeRadialItem exports.
Everything a player sees in the menu comes from Config.Menu in stg-radialmenu/config.lua. Other scripts can also add and remove entries while the server runs, see Exports.
Entry format
Each entry is one slice of the menu. An entry either runs an action or opens a submenu:
Config.Menu = {
{
id = 'police',
label = 'Police',
description = 'Emergency, status, house and action tools',
icon = 'fa-solid fa-shield-halved',
jobs = { 'police' },
submenu = {
{
id = 'emergencybutton',
label = 'Emergency Button',
icon = 'fa-solid fa-bell',
action = function()
TriggerEvent('police:client:SendPoliceEmergencyAlert')
end
},
}
},
}Prop
Type
- Entries appear in the order of the table. Each level shows 6 slices per page. With more than 6, a Next Page button appears. Back returns to the previous page or the parent menu.
- When an entry has both
actionandsubmenu, the action runs and the submenu never opens. jobs,inVehicleandnearVehiclework on every level, not only on the main menu.
Keep every id unique. When two entries share an id, picking either one always runs the first one in the file. Also avoid the ' character in label and description, it stops the title from showing when the cursor is on the slice.
Actions
An action is plain client Lua, so it can do anything a client script can:
action = function()
TriggerEvent('qb-phone:client:GiveContactDetails') -- client event
TriggerServerEvent('police:server:SearchPlayer') -- server event
ExecuteCommand('e sit') -- chat command
endThe default menu calls QBCore resources. Replace each event with the one from the script you use, or remove the entry.
Visibility
| Setting | Entry is shown |
|---|---|
inVehicle = true | While the player sits in a vehicle |
inVehicle = false | While the player is on foot |
nearVehicle = true | While the player is on foot and a vehicle is within 3 metres |
nearVehicle = false | While no vehicle is within 3 metres |
| Both set | When at least one of the two matches |
Built in actions
The script ships these client events so the menu works without extra resources.
Clothing
action = function()
TriggerEvent('stg-radialmenu:ToggleClothing', 'Top')
endThe first press takes the piece off with an animation, the second press puts the same piece back.
| Event | Names |
|---|---|
stg-radialmenu:ToggleClothing | Top, Shirt, Pants, Shoes, Neck, Vest, Mask, Bag, Bagoff, hair, gloves |
stg-radialmenu:ToggleProps | Hat, Glasses, Ear, Watch, Bracelet, visor |
Topopens or closes supported jackets,Shirttakes the whole top layer off.Bagswitches supported bags between their two styles,Bagofftakes the bag off.hairties up supported hair styles,visorflips supported helmet visors.TriggerEvent('stg-radialmenu:ResetClothing')puts back everything that was taken off.
The names are case sensitive: hair, gloves and visor are lowercase. Clothing actions only work on freemode characters (mp_m_freemode_01 and mp_f_freemode_01).
Vehicle doors
action = function()
TriggerEvent('stg-radialmenu:client:openDoor', 5)
endOpens the door when it is closed and closes it when it is open. It works on the vehicle the player sits in, otherwise on the vehicle in front of them. When someone else is driving that vehicle, the door is moved for them too.
| Number | Door |
|---|---|
0 | Driver door |
1 | Passenger door |
2 | Left rear |
3 | Right rear |
4 | Hood |
5 | Trunk |
Exports
Other resources can change the menu at runtime with two client exports. Call them from a client script.
addRadialItem
exports['stg-radialmenu']:addRadialItem({
id = 'myscript_menu',
label = 'My Script',
description = 'Open my script',
icon = 'fa-solid fa-star',
jobs = { 'police' },
action = function()
TriggerEvent('myscript:client:open')
end
})Takes one entry in the entry format and adds it to the end of the main menu. The entry can have its own submenu. Back from a submenu more than one level deep inside an added entry returns straight to the main menu.
removeRadialItem
exports['stg-radialmenu']:removeRadialItem('myscript_menu')Removes the main menu entry with this id. Entries inside a submenu cannot be removed this way.
Good practice
- Every call adds a new entry, even with an
idthat already exists. Add each entry once, and remove it before adding it again. - Entries added with the export are lost when
stg-radialmenurestarts. Start your script after[STG]so the export exists when it runs. - Remove your entries when your own resource stops, so the menu does not keep actions from a stopped script:
AddEventHandler('onResourceStop', function(resource)
if resource == GetCurrentResourceName() then
exports['stg-radialmenu']:removeRadialItem('myscript_menu')
end
end)Still having trouble?
Open a ticket on our Discord. Our team answers around 15 hours a day.