Lua CreateThread inside a function

Hello all,

I am still quite new to Lua programming and FiveM, and I was wondering if you can create a thread inside a client script inside a function. The reason i ask this is the following. Sometimes you’d like a thread to check something in a while loop, but not the entire time the client is connected. So far I’ve only seen scripts where the Citizen.CreateThread is called instantly when the client connects. The following example from the esx_indentity scripts seems a little ineffecient:

Citizen.CreateThread(function()
		while true do
			Citizen.Wait(0)

			if guiEnabled then
				DisableControlAction(0, 1,   true) -- LookLeftRight
				DisableControlAction(0, 2,   true) -- LookUpDown
				DisableControlAction(0, 106, true) -- VehicleMouseControlOverride
				DisableControlAction(0, 142, true) -- MeleeAttackAlternate
				DisableControlAction(0, 30,  true) -- MoveLeftRight
				DisableControlAction(0, 31,  true) -- MoveUpDown
				DisableControlAction(0, 21,  true) -- disable sprint
				DisableControlAction(0, 24,  true) -- disable attack
				DisableControlAction(0, 25,  true) -- disable aim
				DisableControlAction(0, 47,  true) -- disable weapon
				DisableControlAction(0, 58,  true) -- disable weapon
				DisableControlAction(0, 263, true) -- disable melee
				DisableControlAction(0, 264, true) -- disable melee
				DisableControlAction(0, 257, true) -- disable melee
				DisableControlAction(0, 140, true) -- disable melee
				DisableControlAction(0, 141, true) -- disable melee
				DisableControlAction(0, 143, true) -- disable melee
				DisableControlAction(0, 75,  true) -- disable exit vehicle
				DisableControlAction(27, 75, true) -- disable exit vehicle
			else
				Citizen.Wait(500)
			end
		end
	end)

I would like this thread to just be killed once the player is not in a gui, and started again once the player opens the gui. Is this possible in Lua?

You can use Citizen.CreateThread within a lua function. To kill that thread simply break or use a boolean variable instead of true and then change it to false or true depending on what you set it as on initialization.

3 Likes
local start = false

function openThread(bool)
    start = bool
    Citizen.CreateThread(function()
        while true do
            Citizen.Wait(0)
            
            if start then
                DisableControlAction(0, 1,   true) -- LookLeftRight
                DisableControlAction(0, 2,   true) -- LookUpDown
                DisableControlAction(0, 106, true) -- VehicleMouseControlOverride
                DisableControlAction(0, 142, true) -- MeleeAttackAlternate
                DisableControlAction(0, 30,  true) -- MoveLeftRight
                DisableControlAction(0, 31,  true) -- MoveUpDown
                DisableControlAction(0, 21,  true) -- disable sprint
                DisableControlAction(0, 24,  true) -- disable attack
                DisableControlAction(0, 25,  true) -- disable aim
                DisableControlAction(0, 47,  true) -- disable weapon
                DisableControlAction(0, 58,  true) -- disable weapon
                DisableControlAction(0, 263, true) -- disable melee
                DisableControlAction(0, 264, true) -- disable melee
                DisableControlAction(0, 257, true) -- disable melee
                DisableControlAction(0, 140, true) -- disable melee
                DisableControlAction(0, 141, true) -- disable melee
                DisableControlAction(0, 143, true) -- disable melee
                DisableControlAction(0, 75,  true) -- disable exit vehicle
                DisableControlAction(27, 75, true) -- disable exit vehicle
                print('1')
            end
        end
    end)
end

This would be the best way to do it. When NUI is open (esx_idenity) in your case, just make start = true and when NUI is closed off, make start = false.

The thread will only run when function is mentioned example “openThread(true)” and “openThread(false)”.

1 Like

It’s not a good idea.
The fact that you let the while loop on nothing when the gui isn’t open with a 0 Wait is bad. He should do like @Chewy2 said.

Here is a better example to illustrate :

local isOpen = false

local function changeGuiState()
    isOpen = not isOpen -- We switch the isOpen boolean to false or true accordly to the default value

    if not isOpen then
        -- do your things when it closes
        return -- To avoid an else which is pointless we return here.
    end

    Citizen.CreatedThread(function()
        while isOpen do
            -- Do your things here while the gui state is open
        end
    end)
end

If you have more questions, don’t hesitate to ask.

3 Likes

Thank you all for the information, I’ve tried some things and managed to get things to work.

1 Like