Sprinting Bar

Good time of day. I'm trying to make an acceleration that will consume stamina. The code is given below. Everything works perfectly for one player. But for 2 or more, stamina is consumed at the same time for everyone. Please tell me, what am I doing wrong? Thank you in advance.

local shiftKeyBinding = "ability_feet"
local maxStamina = script:GetCustomProperty("MaxStamina")
local isSprinting = false
local baseSpeed = 1000
local sprintingSpeed = 1500

function OnBindingPressed(player, bindingPressed)
    if bindingPressed == shiftKeyBinding then    
        isSprinting = true    
    end
end

function OnBindingReleased(player, bindingReleased)
    if bindingReleased == shiftKeyBinding then
        isSprinting = false     
    end
end

function OnPlayerJoined(player)
    player:SetResource("MaxStamina", maxStamina)
    player:SetResource("CorrentStamina", maxStamina)
    player.bindingPressedEvent:Connect(OnBindingPressed)
    player.bindingReleasedEvent:Connect(OnBindingReleased)
end


function CheckForStaminaChange(player,dt)
    local stamina = player:GetResource("MaxStamina")
    local correntStamina = player:GetResource("CorrentStamina")
    if isSprinting == true  then
        Task.Wait(0.1)
         correntStamina = correntStamina - 1
         player.maxWalkSpeed = sprintingSpeed
             if (correntStamina <0) then 
               correntStamina = 0   
              player.maxWalkSpeed = baseSpeed
           end
         player:SetResource("CorrentStamina", correntStamina)
    end   

    if isSprinting == false  then
              player.maxWalkSpeed = baseSpeed
                Task.Wait(0.1)
                correntStamina = correntStamina + 1
                  if (correntStamina > stamina) then 
                   correntStamina = stamina  
                 end
           player:SetResource("CorrentStamina", correntStamina)
    end
end

function Tick(deltaTime)
    for _, player in ipairs(Game.GetPlayers()) do
        CheckForStaminaChange(player,deltaTime)
    end
end

Game.playerJoinedEvent:Connect(OnPlayerJoined)

Here, I quickly adapted your code:

local shiftKeyBinding = "ability_feet"
local maxStamina = script:GetCustomProperty("MaxStamina")
local sprintTable = {}
local baseSpeed = 1000
local sprintingSpeed = 1500

function OnBindingPressed(player, bindingPressed)
    if bindingPressed == shiftKeyBinding then
        sprintTable[player] = true
    end
end

function OnBindingReleased(player, bindingReleased)
    if bindingReleased == shiftKeyBinding then
        sprintTable[player] = false
    end
end

function OnPlayerJoined(player)
    player:SetResource("MaxStamina", maxStamina)
    player:SetResource("CorrentStamina", maxStamina)
    player.bindingPressedEvent:Connect(OnBindingPressed)
    player.bindingReleasedEvent:Connect(OnBindingReleased)
end

function CheckForStaminaChange(player, dt)
    local stamina = player:GetResource("MaxStamina")
    local correntStamina = player:GetResource("CorrentStamina")
    if sprintTable[player] then
        Task.Wait(0.1)
        correntStamina = correntStamina - 1
        player.maxWalkSpeed = sprintingSpeed
        if (correntStamina < 0) then
            correntStamina = 0
            player.maxWalkSpeed = baseSpeed
        end
        player:SetResource("CorrentStamina", correntStamina)
    else
        player.maxWalkSpeed = baseSpeed
        Task.Wait(0.1)
        correntStamina = correntStamina + 1
        if (correntStamina > stamina) then
            correntStamina = stamina
        end
        player:SetResource("CorrentStamina", correntStamina)
    end
end

function Tick(deltaTime)
    for _, player in ipairs(Game.GetPlayers()) do
        CheckForStaminaChange(player, deltaTime)
    end
end

Game.playerJoinedEvent:Connect(OnPlayerJoined)

What I did was to declare a table called sprintTable. Keys are Player and corresponding value is a boolean (true or false) that is set when the player uses the sprint key. Don't hesitate to ask if you have any questions about this!

By the way, some tips regarding your original code:

  • You can write if isSprinting instead of if isSprinting == true. Same goes with if isSprinting == false, this can be replaced by if not isSprinting.
  • Also, you don't have to do
if isSprinting == true then 
...
end
if isSprinting == false then
...
end

It's easier to use else

if isSprinting then
...
else
...
end

A huge human thank you! Everything works! I will say right away that I communicate with you through a translator, so I apologize in advance for possible mistakes and poor English. I'll probably take advantage of your suggestion and ask a couple of stupid questions in order to get smart answers to them. :))

  1. Do I understand correctly that every time you click on the Shift, the value for each player in the table (true / false) is overwritten, and not a new one is added?
  2. I want my stamina to recover not immediately, but with some pause. Where and how do I set this pause?
  1. Everytime a player uses Shift, the value for THIS player is overwritten. No new value is added, since keys are unique in Lua tables (and here the key (which is the Player) doesn't change, only its value does).

  2. A solution would be to store the current timestamp (obtainable with os.time()) when the player releases Shift. Then, before adding stamina to the player, check if enough time has passed by reusing os.time(). For example, here we check for a 5 second delay:

local sprintTable = {}
local shiftReleased = {}

function OnBindingReleased(player, bindingReleased)
    if bindingReleased == shiftKeyBinding then
        sprintTable[player] = false
        shiftReleased[player] = os.time()
    end
end
...

if os.time() - shiftReleased[player] > 5 then
     ...
     correntStamina = correntStamina + 1
     ...
end

Hey,

The problem comes from your "isSprinting" variable. It isn't specific to each player so when one sprints, it becomes true to everyone and everyone starts losing stamina!

You could use a table { player // isSprinting } to fix this!

Thanks for the reply. I'm very sorry, but how do I use this table? I'm just starting to learn programming. Can I have an example or a link to a usage example?

Everything is fine, in the end it worked. At the beginning, the game was swearing, then I realized that it was necessary to add shift Release[player] = 0 to OnPlayerJoined, otherwise this value was missing, because it was added only after pressing the Shift. The only question still on this topic. I didn't find os.time () in the documentation , only time(), but the program accepted both. Are these the same functions or is there a difference? Thank you again for your help and for introducing a useful feature.))

Yup, there is a difference between the two:

According to the Core documentation:
time() - Returns the time in seconds (floating point) since the game started on the server.

os.time() returns the current date and time, coded as a number. (In most systems, that number is the number of seconds since some epoch.)

So the values won't be the same but in your case, both work.

I understand, thank you again )))