I am trying to create a stamina system similar to a souls game in which actions consume stamina. Everything is working as intended, however I do not know how to make it so that stamina regen is halted temporarily when you do an action. I am currently setting a boolean to true/false in order to start stamina regen, however this comes with some problems.
When I try to disable regen, for example, I want the regen to come back a second after the action is done. However, this gets weird when you string several actions together such as this:
The dash and run buttons are connected, you have to hold the dash button to start running.
The player dashes/rolls, cancelling the stamina regen and enabling it after 1 second
The player starts running before the stamina regen comes back
Pressing the dash button should cancel stamina regen, however because of the roll prior, the regen comes back while the player runs
This is obviously an issue, however I do not know a way in which I can fix it. I was thinking of potentially checking if another input was made before the boolean changes to false again, however I don’t exactly know how to create this considering how the stamina system stretches through several scripts.
I will post the code if necessary, however a fair amount of it might not have much correlation to the issue at hand, considering how it also functions as the code for the roll.
Make sure to put a variable stating if the player is running or not, that way you can use it in an if statement to judge whether you start regenerating stamina or not
This best works when there is an inputEnded function
I also recommend using a variable to test how many times sprint has been activated.
Here is a snip-it of my code from an old game of mine (Pay attention to the threads variable)
This is being activated after the input has begin
if input.KeyCode == Enum.KeyCode.LeftShift then
old_speed = character.Humanoid.WalkSpeed
running = true
SprintValue.Value = true
threads = threads + 1
print(threads)
while stamina > 0 and running do
if character.Humanoid.WalkSpeed > old_speed + Sprint_Add then
old_speed = character.Humanoid.WalkSpeed - Sprint_Add
end
character.Humanoid.WalkSpeed = old_speed + Sprint_Add
stamina = stamina - 1
script.Parent:TweenSize(UDim2.new(stamina/100,0,1,0),"Out","Linear",0)
wait()
if stamina <= 0 then
character.Humanoid.WalkSpeed = old_speed
end
end
end
This is being activated after the input has ended (There is more code behind it but this post was getting too long)
while stamina < 100 and not running do
if cooldown == true then
cooldown = false
wait(1.5)
if threads - 1 ~= 0 then
threads = threads - 1
print(threads)
return
else
threads = threads - 1
print(threads)
end
end
I am using a boolean value located in ReplicatedStorage. I am now also trying to use UserInputService based on your response, however what I thought might work does not stop the stamina from regenerating. Basically what I am doing now is using UIS to check for when input involving the spacebar begins and ends.
actionCheck is the value which starts and stops the stamina regen, while currentAction just checks if the player is still rolling, stopping actionCheck from starting up.
UIS.InputBegan:Connect(function(key)
if key == Enum.KeyCode.Space then
actionCheck.Value = true
end
end)
UIS.InputEnded:Connect(function(key)
if key == Enum.KeyCode.Space then
if currentAction.Value == false then
task.wait(1)
actionCheck.Value = false
else
currentAction.Changed:Wait()
end
end
end)
Alright so this may be just a bit late but I have worked out a solution to this issue.
One of the problems faced while trying to initially script this had been that all parts of the moveset which consume stamina were placed into separate scripts. This can be solved in two ways.
Use global variables through either module scripts or _G
Move everything to one script
For the purpose of the game I have done both.
From there it became a simple solution of just using tick() and measuring from when an action was last performed.
To demonstrate, here are parts of the script for the stamina system I am using:
--module script
local module = {
["maxStamina"] = 80,
["stamina"] = 80,
["exhausted"] = false, -- prevents any actions if stamina is depleted
["currentAction"] = false,
["lastAction"] = tick() --the main variable that determines when stamina should regen
}
return {
get = function(item)
return module[item]
end,
set = function(item, value)
module[item] = value
end,
-- get and set basically just are for retrieving the variables in another script
depleteStamina = function(amnt)
module.stamina -= amnt
if module.stamina <= 0 then
module.stamina = 0
module.exhausted = true
return false
else
return true
end
-- the two returns here are just for stopping held actions such as running if stamina is out
end
}
-- local moveset script - part that handles stamina regen
RS.RenderStepped:Connect(function()
if tick() - genMod.get("lastAction") >= 2 then -- after two seconds remove exhausted and regenerate stamina
genMod.set("exhausted", false)
genMod.set("stamina", genMod.get("stamina") + 0.75)
if genMod.get("stamina") > genMod.get("maxStamina") then genMod.set("stamina", genMod.get("maxStamina")) end
end
end)
This code has been able to work for me for some time now as this was made about a month ago.