Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to detect if player is not moving for a certain time?

I want to check when the player is idle for 5 seconds (not jumping not using WASD or arrow keys) and after that to run a code. I tried with User Input Service (with InputBegan and Ended), but if a player is holding more than one key (W and A for an example) and releases one of them the idle script will run thinking he is idle when he is not.

isWalking = true

--the input began event
uis.InputBegan:Connect(function(input, typing)

if not typing and input.UserInputType == Enum.UserInputType.Keyboard and (input.KeyCode == Enum.KeyCode.W or input.KeyCode == Enum.KeyCode.S or input.KeyCode == Enum.KeyCode.A --[[..etc]]) then

isWalking = true

end
end)

--the input ended event
uis.InputEnded:Connect(function(input, typing)

	if not typing and input.UserInputType == Enum.UserInputType.Keyboard and (input.KeyCode == Enum.KeyCode.W or input.KeyCode == Enum.KeyCode.S or input.KeyCode == Enum.KeyCode.A or input.KeyCode == Enum.KeyCode.D or input.KeyCode == Enum.KeyCode.Space or input.KeyCode == Enum.KeyCode.Up or input.KeyCode == Enum.KeyCode.Down)then

		isWalking = false	
	
		wait(5)

		if isWalking == false then
--code
end

end

end)

Does anyone know how could I make it work out properly?

2 comments

0

Should of mentioned I first tried it with the Humanoid's Running event. It had a similar effect, as if you start running before 5 seconds have passed and if you remain at constant speed the code will run unless something affects your speed. If nothing else works I may stick to that.

2 answers

✓ Accepted answer

Copy and paste the code into your script

Using the UserInputService is a much better approach than checking for Humanoid.HumanoidStateType because what you initially wanted was to check if players were pressing certain keys.

local uis = game:GetService("UserInputService")

local hasMoved = false
local timer = os.time()
local lastKeyPressed = nil

local MAX_SECONDS = 5

--the input began event
uis.InputBegan:Connect(function(input, typing)
	if not typing and input.UserInputType == Enum.UserInputType.Keyboard and (input.KeyCode == Enum.KeyCode.W or input.KeyCode == Enum.KeyCode.S or input.KeyCode == Enum.KeyCode.A or input.KeyCode == Enum.KeyCode.D or input.KeyCode == Enum.KeyCode.Space or input.KeyCode == Enum.KeyCode.Up or input.KeyCode == Enum.KeyCode.Down) then	
		hasMoved = true	
		timer = os.time()
		lastKeyPressed = input.KeyCode
	end
end)

--the input ended event
uis.InputEnded:Connect(function(input, typing)
    if not typing and input.UserInputType == Enum.UserInputType.Keyboard and (input.KeyCode == Enum.KeyCode.W or input.KeyCode == Enum.KeyCode.S or input.KeyCode == Enum.KeyCode.A or input.KeyCode == Enum.KeyCode.D or input.KeyCode == Enum.KeyCode.Space or input.KeyCode == Enum.KeyCode.Up or input.KeyCode == Enum.KeyCode.Down) then        
		if lastKeyPressed == input.KeyCode then	
			hasMoved = false
			timer = os.time()
		end
	end
end)

local function CheckIdle(tempTimer)
	print(timer)
	print(tempTimer)		
	tempTimer = tempTimer - timer
	print("Seconds since last key pressed: "..tostring(tempTimer))
	
	if tempTimer >= MAX_SECONDS then
		return true
	else 
		return false
	end
end

while true do	
	print("Player was still moving?: "..tostring(hasMoved))
	if not hasMoved then
		local tempTimer = os.time()
		if CheckIdle(tempTimer) then
			print("Player has not moved")
			--Do code
			break 
		end
	end
	wait()
end

What you needed was a While loop to do the counting for you instead of counting inside the InputEnded event.

Your second problem is when multiple keys are pressed and released(like you mentioned). That is solved by checking if the KeyCode from InputEnded was the same as the "lastKeyPressed" from the InputBegin - if it's not, then the player has pressed a new key.

1 comment

0

Thank you for your time, I am going to test this now

I tried my old code with the Humanoid's Running event, but instead of putting the whole thing under one event I made two - and surprisingly it worked. I'll give both the old code and the new one below if someone's interested:

--old semi-working code:
isWalking = true

hum.Running:Connect(function(speed)
if speed>1 then
		isWalking = true
else
		isWalking = false
wait(5)

	if isWalking == false then
--code
	end
end
end)

--new working code:
isWalking = true

hum.Running:Connect(function(speed)
if speed>1 then
		isWalking = true
end
end)

hum.Running:Connect(function(speed)
	if speed<1 then
		isWalking = false		
		wait(5)
		if isWalking == false then
--code
end
end
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.