Hey so I have this simple thing that I want to add to my player overhead but I had some issues figuring out how to effectively do it.
I’m using UserInputService to detect whether the player is WindowFocused or not.
My main question is how can I manage to count the amount of time the player has been AFK for & display the amount of time in 00:00. What is the best possible way to accomplish this?
Code below.
Server
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local afkEvent = Instance.new("RemoteEvent")
afkEvent.Name = "AfkEvent"
afkEvent.Parent = ReplicatedStorage
local function setAfk(player, afk)
local overhead = player.Character:WaitForChild("HumanoidRootPart"):WaitForChild("OverheadGui")
local overheadText = overhead.Background:WaitForChild("AFK")
if afk then
overheadText.Visible = true
else
overheadText.Visible = false
end
end
afkEvent.OnServerEvent:Connect(setAfk)
Client
local UserInputService = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local afkEvent = ReplicatedStorage:WaitForChild("AfkEvent")
local function focusGained()
afkEvent:FireServer(false)
end
local function FocusedReleased()
afkEvent:FireServer(true)
end
UserInputService.WindowFocused:Connect(focusGained)
UserInputService.WindowFocusReleased:Connect(FocusedReleased)
As of right now only shows AFK text when you’re not windowfocused.
You can use tick() for time and os.date to format the seconds you got into 00:00:00. I couldn’t find anything that could turn it into 00:00 instead.
For the format strings, use this documentation and scroll down to os.date: os | Roblox Creator Documentation
Like this:
local function AFKOn()
local StartTime = tick()
end
local function AFKOff()
local FinishTime = os.date("%X", StartTime - tick())
return FinishTime
end
For checking if the user is AFK or not, you could probably use task.delay to run a function every few seconds and then check if the position of the character has always been same or not, I came up with this script, let me know if it works or not:
--[[ Server Script in StarterCharacterScripts,
as you can get the character then and do everything on the server
instead of the client
--]]
local Players = game:GetService("Players")
local Character = script.Parent -- The script is parented under the character when the player joins
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local LatestPosition = nil -- we log the latest hrp position in the variable
local DelayBetweenRuns = 10 --seconds
local Runs = 0 -- how many times the function has ran
local AFK = false -- is afk or not
local function CheckForIdle()
if LatestPosition ~= nil then
if (HumanoidRootPart.Position - LatestPosition).Magnitude > 5 then -- if latest position greatly differs from current position, then afk is set to false
AFK = false
Runs = 0
return CheckForIdle -- terminate function
end
end
LatestPosition = HumanoidRootPart.Position
Runs += 1
if Runs >= 2 then -- if how many times the function has been ran is more than 2 and player has still not moved then afk is set to true
AFK = true
end
end
task.delay(DelayBetweenRuns, CheckForIdle)
Interesting way to check if a Player is idle, I understand exactly what you’re doing in the CheckForIdle function.
local function AFKOn()
local StartTime = tick()
end
local function AFKOff()
local FinishTime = os.date("%X", StartTime - tick())
return FinishTime
end
Do I just call these functions in the if statements of the CheckForIdle so when the Player isn’t moving we’d call AFKOn there and then the opposite for AFKOff?
couldnt you detect inputs using UIS.InputBegan? instead of spam checking if the humanoid moved, (small example case) but what if the humanoid is on a moving brick?
When the window loses focus, set the variable startAFK to tick(). When the window is focused, set the same variable to zero. Now every render step, get the time spent being afk like this: startAFK == 0 and 0 or tick() - startAFK