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. :))
- 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?
- I want my stamina to recover not immediately, but with some pause. Where and how do I set this pause?
-
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).
-
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 )))