Hmm, it seems that you don’t clearly understand my point is yet, even if you are using BindableEvent
, it is clear that you are still firing event, which mean’s that you can save the time when a script fired the event and using a spawn(function()
creating A new thread adding a wait()
for when the regen can start, then compare the the tick()
of when it was last fired, to the current time, with a while loop if the condition is a true then while loop will start, once A script fired another event the while loop will stop (the old thread will just end). creating another thread.
I think I understand this better, when you explain it like this. I will try and make smth!
I already made something using only logic! I don’t have to use tick() as long as I just change some values when it spawns a function and when it ends. It basically just checks if there is already a loop going on, and if there is it returns
That’s A good idea, my idea was from checking if the player is spamming an event, never really though of just using boolean if the event was fired or not. I might have to bookmark this for future reference.
Hmm, I only got it to work partially. When I start running it will decrease the stamina, after 2 seconds it will start generating, and if I start running mid-generate it will stop the generating as it should. However, if I start running and after 2 seconds it will generate and then jump, it will keep generating. I don’t know how to fix this, I thought these booleans would help but they didn’t
local RS = game:GetService("ReplicatedStorage")
local STAM_REMOTE = RS:WaitForChild("Remotes"):WaitForChild("Stamina")
local STAM_BIND = RS:WaitForChild("Remotes"):WaitForChild("StaminaBind")
local run = false
local timer = 0
local canRegen = true
local canSpawn = true
STAM_REMOTE.OnServerEvent:Connect(function(plr, action)
local stamina = plr.Character:WaitForChild("Stamina")
if action == "startedRun" then
run = true
canRegen = false
while run == true do
if stamina.Value >= 1 then
stamina.Value -= 1
wait(0.05)
if stamina.Value == 0 then
run = false
end
else
stamina.Value = 0
break
end
print(stamina.Value)
end
elseif action == "stoppedRun" then
run = false
wait(2)
if canRegen == false then
canRegen = false
canSpawn = true
end
canRegen = true
spawn(function()
if canSpawn == true then
canSpawn = false
while canRegen == true do
if stamina.Value < 100 then
stamina.Value += 1
wait(0.1)
print(stamina.value)
elseif stamina.Value == 100 then
canRegen = false
end
end
canSpawn = true
end
end)
elseif action == "jump" then
if stamina.Value >= 10 then
stamina.Value -= 10
else
stamina = 0
end
print(stamina.Value)
wait(2)
if canRegen == false then
canRegen = false
canSpawn = true
end
canRegen = true
spawn(function()
if canSpawn == true then
canSpawn = false
while canRegen == true do
if stamina.Value < 100 then
stamina.Value += 1
wait(0.1)
print(stamina.value)
elseif stamina.Value == 100 then
canRegen = false
end
end
canSpawn = true
end
end)
end
end)
STAM_BIND.Event:Connect(function(plr, action)
local stamina = plr.Character:WaitForChild("Stamina")
if action == "punch" then
if stamina.Value >= 5 then
stamina.Value -= 5
else
stamina = 0
end
print(stamina.Value.. " punch")
end
end)
I knew you would have this problem, because the problem with running is that you also need to check if the speed is above or below 0.
No, this is already being checked, when run = true, the player is actually running, this is also checked on client.
The issue is that whenever i jump, it doesn’t cancel the other spawned function
From what I saw in your script your should be only using 1 spawn(function()
put it at the end.
Yea that’s what i just thought of, what about in the bindable, how would they cancel eachother
I would highly recommend using an array, so that the bindable event would be able to access it as well. Just use the name of the player as the variable.
Can you give me some example code? I don’t know how implementing an array / table would work here other than just normal booleans
Instead of using local canRegen = true; local canSpawn = true
you should just use data[player.Name]["canRegen"] = true; data[player.Name]["canSpawn"] = true
Note: if you wan’t to remove the player from the array just create a
PlayerRemoving
function and just set thelastCall[player.Name] = nil.
It sounds way more complicated than it really should be, maybe I can use coroutines to yield until 2 seconds have passed since an event
local data = {}
STAM_REMOTE.OnServerEvent:Connect(function(plr, action)
data[plr.Name]["canRegen"] = true
data[plr.Name]["canSpawn"] = true
end)
STAM_BIND.Event:Connect(function(plr, action)
data[plr.Name]["canRegen"] = true
data[plr.Name]["canSpawn"] = true
end)
where would i define data (max chars)
What do you mean by data (max chars) are you also planning to add a max characters to be added?
no haha, i just couldnt send the message if i didnt add some more text
Just asking for how and where i should define data
The reason why I recommended using array is that once you have multiple player accessing the function they would have some complication with the local variable, lets say one of the player is running and the other is not running with no stamina, the player who is not running would not be able to generate A stamina since local canRegen = false
.
local data = {}
STAM_REMOTE.OnServerEvent:Connect(function(plr, action)
data[plr.Name]["canRegen"] = true
data[plr.Name]["canSpawn"] = true
end)
STAM_BIND.Event:Connect(function(plr, action)
data[plr.Name]["canRegen"] = true
data[plr.Name]["canSpawn"] = true
end)
the data array should be created outside of the thread and only be assigned to each player inside the threat right?
Yes, you can still try to use print(data)
check if the name of the player who fired is there.