Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I make my game check for players who are afk?

Asked by 3 years ago

I've been making an Afk button in my round based PVP game, but if there are 2 players when a round starts and one is afk, the other player will automatically win and get points. The afk option works fine. So, my question is, how can I make the game check to see if there are at least 2 people who aren't Afk?

(There are 2 values, "NotPlaying" and "Playing")

Here is the script:

while true do

    Status.Value = "Waiting for enough players"

    repeat wait(1) until game.Players.NumPlayers >= 2

    Status.Value = "Intermission"

    wait(20)

    local AvailableMaps = MapsFolder:GetChildren()

    local ChosenMap = AvailableMaps[math.random(1,#AvailableMaps)]


    local ClonedMap = ChosenMap:Clone()
    ClonedMap.Parent = workspace

    Status.Value = "Picking a map..."

    local plrs = {}

    for i, player in pairs(game.Players:GetPlayers()) do
        if player:FindFirstChild("Playing") and player then
            table.insert(plrs,player)
        end
    end

    wait(2)

(This is only the part of the script where it adds the players)

1 answer

Log in to vote
3
Answered by
appxritixn 2235 Moderation Voter Community Moderator
3 years ago
Edited 3 years ago

My solution to this is to create an afk timer.

function countdown(numValue)
    while wait(1) do
        numValue.Value -= 1
        if numValue.Value == 0 then -- if the timer is done
            -- Player is considered afk
            -- Do stuff
            coroutine.yield() -- yield / pause the function (it is coroutine wrapped)
        end
    end
end

game.Players.PlayerAdded:Connect(function(player)
    local timer = Instance.new("NumberValue",player)
    timer.Name = "AFK Timer"
    timer.Value = 30 -- How long a player can be still before being 'afk', change this value if you wish
    local default_time = timer.Value -- stores the default timer length
    player.CharacterAdded:Connect(function(char)
        local humanoid = char.Humanoid
        humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
            if humanoid.MoveDirection ~= Vector3.new(0,0,0) then -- if the player moves
                timer.Value = default_time -- reset timer
            end
        end)
        local countdown = coroutine.wrap(countdown) -- create the coroutine wrapped function
        countdown(timer) -- execute the coroutine wrapped function
        local debounce = false
        while wait(0.1) do
            if timer.Value == 0 then
                debounce = true -- allow the countdown to be started again
            end
            if timer.Value > 0 and debounce then -- if the countdown can be started and the timer's value is above 0
                debounce = false -- dis-allow the countdown to be started, it is already started
                countdown() -- execute the coroutine wrapped function
            end
        end
    end)
end)

I have provided comments on almost every line to explain what is happening. Yes, in some cases it was probably not needed.

Anyway, there is a section of code within the countdown function:

if numValue.Value == 0 then -- if the timer is done
            -- Player is considered afk
            -- Do stuff
            coroutine.yield() -- yield / pause the function (it is coroutine wrapped)
        end

'-- Do stuff' should be replaced with your code to set the player as 'afk'.

timer.Value = 30 -- How long a player can be still before being 'afk', change this value if you wish

The value, as it says, can and should be changed according to what you would consider being 'afk' (in seconds).

If you wish to contact me because you don't understand something I have said, or wish to get help with something else, feel free to contact me on Discord (phxntxsmic#2021)

EDIT

As discussed in discord, this is what you were looking for (just updating my answer):

local players = game.Players
local afk = {}
for _,player in ipairs(players:GetChildren()) do
  if player:FindFirstChild("IsAFK").Value == true then
    table.insert(afk,player)
  end
end
if #players:GetChildren() - 2 >= #afk then
  -- 2 or more players are not afk
end
1
Optionally, you could do a check in other scripts for 'player:FindFirstChild("AFK Timer").Value'. (When it is equal to 0, the player would be considered afk) appxritixn 2235 — 3y
Ad

Answer this question