AFK detector while loop overlaps

So I have this as an AFK detector. Whenever a player does nothing STRAIGHT for 40 seconds I want the event to fire. Although currently when a player does nothing for 40 seconds total (with input inbetween), it fires the event. So the timer doesn’t restart I assume? Btw the while loop at the bottom is just the initial checker as when the script is inserted in the PlayerGui they may already be AFK and the InputEnded won’t be triggered to actually tell if they’re Afk. Help is appreciated.

--> SERVICES
local UIS = game:GetService("UserInputService")

--> LOCAL VARIABLES
local Idle = true
local Time = 40

--> FUNCTIONS
UIS.InputEnded:Connect(function()
	Idle = true
	Time = 40
	while Idle == true do
		wait(1)
		Time = Time - 1
		if Time == 0 then
			workspace.Console.Roles.NoActivity.Value = true
			game.ReplicatedStorage.MainUI_Events.AFK_Send:FireServer()
			script:Destroy()
		end
	end
end)

UIS.InputBegan:Connect(function()
	Idle = false
end)

--> CODE
while Idle == true do
	wait(1)
	Time = Time - 1
	if Time == 0 then
		workspace.Console.Roles.NoActivity.Value = true
		game.ReplicatedStorage.MainUI_Events.AFK_Send:FireServer()
		script:Destroy()
	end
end

Does your while run at the end of the code until Idle switches to false and the script ends? You are using the wrong while in your event handler? Try to use

--> SERVICES
local UIS = game:GetService("UserInputService")

--> LOCAL VARIABLES
local Idle = true
local Time = 40

--> FUNCTIONS
UIS.InputEnded:Connect(function()
	Idle = true
	Time = 40
end)

UIS.InputBegan:Connect(function()
	Idle = false
	print("afk disabled")
end)

--> CODE
while wait(1) do
	if Idle then
		Time = Time - 1
		if Time == 0 then
			print("afk enabled")
		end
	end
end
local userInput = game:GetService("UserInputService")

local isAfk = false
local afkLength = 0

userInput.InputBegan:Connect(function(key, processed)
	isAfk = false
	afkLength = 0
end)

userInput.InputEnded:Connect(function(key, processed)
	task.delay(120, function()
		if not isAfk then
			isAfk = true
			task.spawn(function()
				while true do
					task.wait(1)
					if isAfk then
						afkLength += 1
					else
						--Fire server here.
						return
					end
				end
			end)
		end
	end)
end)

This works better than OPs script but false positive still happen when someone hold 2 buttons then release 1 while still holding the other and not doing any more inputs.

It’s rare but what if someone held w to move and press a button, it will trigger the timer even though they are still holding w.

Here is a script that will not bugging as written above. It doesn’t respond to the mouse:

local UIS = game:GetService("UserInputService")
local Move = false
local Time = 40

UIS.InputBegan:Connect(function(input)
	if input.KeyCode ~= Enum.KeyCode.Unknown then
		local KeyStart = Instance.new("StringValue")
		KeyStart.Name = tostring(input.KeyCode)
		KeyStart.Parent = script	
		Move = true
	end
end)

UIS.InputEnded:Connect(function(input)
	local KeyEnd = script:FindFirstChild(tostring(input.KeyCode))
	if KeyEnd ~= nil then
		KeyEnd:Destroy()
	end	
	Move = false
	
	if script:FindFirstChildOfClass("StringValue") == nil then
		while task.wait(1) do
			if Move == false then
				Time = Time - 1
				if Time <= 0 then
					print("kick")
				end
			else
				Time = 40
				break
			end
		end
	end
end)

My mistake. I’ve improved the code and now it should work better I hope

--> SERVICES
local UIS = game:GetService("UserInputService")

--> LOCAL VARIABLES
local Idle = true
local Time = 40
local ActivedInputs = 0

--> FUNCTIONS
UIS.InputEnded:Connect(function(input)
	if input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Focus then
		ActivedInputs -= 1
		if ActivedInputs <= 0 then
			Idle = true
			Time = 40 -- Reset Time
			ActivedInputs = 0
			print("Idle = true. Time reset")
		end
	end 
end)

UIS.InputBegan:Connect(function(input)
	if input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Focus then
		ActivedInputs += 1
		Idle = false
		print("Idle = false")
	end
end)

--> CODE
while wait(1) do
	if Idle then
		Time = Time - 1
		if Time == 0 then
			print("afk enabled")
		end
	end
end
1 Like