Vehicle Control Menus

Smart Vehicle supports custom vehicle control menus and we've included one with our Recovery Truck resource by default.

Adding vehicle menus

This guide will show you how to enable Smart Vehicle to work with a custom menu you may wish to create (or just modify our recovery truck one). This guide does not show you how to design or code a custom menu, with this requiring knowledge of CSS, HTML and JS.

An example of our Recovery Truck menu, allowing you to control all parts of the truck

Example Menu

We've made an example menu available for download below. Feel free to use this as a template for your own Smart Vehicle menus as these files will make it pretty simple to add this to your own vehicles, with just needing to change the controls and button positioning on the menu.

First step, create your menu

Firstly, design and create your menu which should be in a third party resource separate to Smart Vehicle. For our Recovery Truck vehicle, we've included the menu within the resource files of the recoverytruck folder and therefore defined the HTML file as an nui reference in the manifest.

The file directory of our recovery truck resource

Once you have created the menu, you'll need to create a couple of exports from a lua file.

Export 1: getPressedKey

function getPressedKey()
    if not controlPressed then return 0 end
    return control
end

exports("getPressedKey", getPressedKey);

You should have an export named getPressedKey which allows Smart Vehicle to constantly check which key is being pressed by the user. This is how we are doing it for our Recovery Truck resource, however there are many different ways of doing it:

main.js file:

document.querySelectorAll(".movement-button").forEach(function(button) {
        button.addEventListener("mousedown", function() {
    
            fetch(`https://${GetParentResourceName()}/submitButtonPress`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json; charset=UTF-8',
                },
                body: JSON.stringify({
                    control: button.dataset.control,
                })
            }).then(resp => resp.json()).then(resp => console.log(resp));
        });

        button.addEventListener("mouseup", function() {
    
            fetch(`https://${GetParentResourceName()}/submitButtonRelease`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json; charset=UTF-8',
                },
                body: JSON.stringify({
                    control: button.dataset.control,
                })
            }).then(resp => resp.json()).then(resp => console.log(resp));
        });
    });

client.lua file:

RegisterNuiCallback('submitButtonPress', function(data, cb)
    control = data.control

    controlPressed = true

    cb({})
end)

RegisterNuiCallback('submitButtonRelease', function(data, cb)
    control = 0

    controlPressed = false

    cb({})
end)

This shows a js file constantly sending a message back to the lua file every time a player presses the button. We are using mouseup and mousedown events for this so that a player is able to hold down the button, rather than continously press it. These events pass the data to the lua file which then allows Smart Vehicle to find out which key is being pressed using the getPressedKey export.

Export 2: openMenu

You will need to add another export named openMenu which allows us to open the menu from the Smart Vehicle resource, either when a player starts controlling the vehicle or when they press a defined key, which we will configure later. This is how we've setup this export for our menu:

In this openMenu function, it is important that you use the SetNuiFocus native to allow a player to click on the buttons (if you wish), as seen below.

client.lua file

function openMenu()
    SendNUIMessage({
        type = 'openMenu'
    })
    SetNuiFocus(true, true)
end

exports("openMenu", openMenu);

main.js file

window.addEventListener('message', (event) => {
    if (event.data.type === 'openMenu') {
        openMenu();
    }
});

Closing the Menu

Smart Vehicle only opens the menu for you and will not close it for the user. Therefore, you'll need to add some functionality for closing the menu yourself. For example, we've added a button called Close Menu on our Recovery Truck menu, which looks like this:

main.js

document.getElementById("close-menu-button").addEventListener("click", function() {
        document.querySelectorAll("#control-panel")[0].style.display = "none";
        fetch(`https://${GetParentResourceName()}/closeMenu`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json; charset=UTF-8',
            },
            body: JSON.stringify({
            })
        }).then(resp => resp.json()).then(resp => console.log(resp));
    });

client.lua

RegisterNuiCallback('closeMenu', function(data, cb)
    SendNUIMessage({
        type = 'closeMenu'
    })
    SetNuiFocus(false, false) 
    cb({})
end)

It is important that you fetch back to the lua file to enable the SetNuiFocus native to run, rather than just setting the display to none on the menu.

Setting up the menu in the data file

Next, you'll need to open the vehicle data file, such as the recovery.lua file and add a new section called menu, as seen below:

Code:

menu = { 
        enabled = true,
        resourceName = "recoverytruck",
        menuControls = {
            openAuto = false,
            openMenuKey = 311,
            -- Export to open menu should be named openMenu()
        }
    },

After setting enabled to true, you'll need to set the resource name of the third party resource where the menu is hosted, such as recoverytruck in our case.

Next, you'll need to configure the menuControls section. By setting openAuto to true, SmartVehicle will call the openMenu() export on your resource every time a player starts controlling.

Next, you'll need to set the openMenuKey which will be handled by Smart Vehicle, which will open the menu whenever a player presses this key whilst controlling.

Last updated

Was this helpful?