Cant break while true loop

I am trying to make shot power increase until the user stops holding mousebutton1 but it keeps increasing even after holding is set to false. Here is my code:

re.OnServerEvent:Connect(function(player, holding)
	print(holding)
	while true do
		if holding == true then
		shotpower = shotpower + 5
		wait(0.1)
		print(shotpower)
		end

		if holding == false then
			break
		end
	end
end)

I have been searching for the last 30 minutes on how to fix this, but I couldn’t find any solutions from anywhere. Can someone help? Thanks.

1 Like

Okay let me try to explain this without yapping on about something else

So basically, even if you fire the RemoteEvent again, it’ll basically “run a clone of this function”. It doesn’t run this “clone of the function” again

So in this function, “holding” will still be the same value

Now obviously you could make a local variable in this script, but you’d need a separate RemoteEvent to change it

I wouldn’t recommend writing it like this anyways, I can give some pointers if you’d like

It also does seem like:

Is being stored on the server for every player. I would probably recommend either adding a IntValue or NumberValue into the Player (this is the one I don’t recommend as much)

OR


You could create some sort of “player tracker” that has a bunch of stats etc like this:

local Stats = {}

game.Players.PlayerAdded:Connect(function(Player)
   Stats[Player.Name] = {
      ["ShotPower"] = 0
   }
end)

This isn’t directly related to your current issue but I noticed it so I thought that I should point it out. Unless I’m completely wrong cuz I’m guessing from the provided code snippet.

That’s it

5 Likes

Why don’t you just do

while holding do
	shotpower = shotpower + 5
	wait(0.1)
	print(shotpower)
end
2 Likes

Because i need to be able to detect hold = false to break it

I’m slightly confused, a while loop loops until the boolean is false, is that what you want?

Forgot to mention. The shotpower is related to the amount of force that is going to go onto the ball when you shoot it. So i am using

lookvector * 20 * shotpower

it isnt a player stat

1 Like

Here’s uh something I came up with

local HoldBegan = path.to.remote
local HoldEnded = path.to.remote
local CurrentLoop

local function loopIncrement()
   return task.spawn(function()
      while task.wait(0.1) do
         shotpower += 5
         print(shotpower)
      end end)
end

HoldBegan.OnServerEvent:Connect(function(Player)
   currentLoop = loopIncrement()
end)

HoldEnded.OnServerEvent:Connect(function(Player)
    if not currentLoop then return end
    task.cancel(currentLoop)
    currentLoop = nil
end)

I can explain it too so yeah lmk if you need me to since I can see that it might be confusing

and I can tell this isn’t the best method but I’m pretty sure it works

Wait is this about holding a button? I’m not sure, I just came up with that

And replace “path.to.remote” with the actual RemoteEvents

This is basically the same as what the OP wrote! The loop still will not be broken!

A not-so-efficient way of doing this:

local holding = false

re.OnServerEvent:Connect(function(player, newHoldingValue)
	holding = newHoldingValue

	print(holding)
end)

while true do
	if holding == true then
		shotpower = shotpower + 5

		print(shotpower)
	end

	task.wait(0.1)
end

It probably works and the loop in this one doesn’t need to be broken!

2 Likes

I do have to admit, that is kinda smart.

1 Like

Nice I think this could work. Only thing is that when you run this, this while loop will occupy all the code, which won’t let it execute; even the RemoteEvent

You just need to wrap it in a task.spawn or a coroutine and you should be good :+1:

More conventional method here

1 Like

This worked very well. Thanks very much for y’alls help!

2 Likes

Let’s break this

local HoldBegan = path.to.remote
local HoldEnded = path.to.remote
local CurrentLoop

local function loopIncrement()
   return task.spawn(function()
      while task.wait(0.1) do
         shotpower += 5
         print(shotpower)
      end end)
end

HoldBegan.OnServerEvent:Connect(function(Player)
   currentLoop = loopIncrement()
end)

HoldEnded.OnServerEvent:Connect(function(Player)
    if not currentLoop then return end
    task.cancel(currentLoop)
    currentLoop = nil
end)

down!

local CurrentLoop

A undefined variable for which we’ll use to reference our loops

return task.spawn(function()
      while task.wait(0.1) do
         shotpower += 5
         print(shotpower)
      end end)

I’m returning the while loop wrapped in task.spawn so later I can cancel it which essentially “destroys the loop”

The rest is more easy to understand but if you need me to explain that, I can too

mb I didn’t see the solution

1 Like

Yes this makes sence but in

return task.spawn(
      while task.wait(0.1) do
         shotpower += 5
         print(shotpower)
      end)

i had an error at task.spawn(
code
end)
in which the “while” is underlined in red

Am i inserting it correctly?

1 Like

Oh my bad, I should’ve added the function keyword like this

return task.spawn(function()
      while task.wait(0.1) do
         shotpower += 5
         print(shotpower)
      end end)

I know the way I wrote it looks weird, if you indent it; it’ll look normal

1 Like

okay thank you for your help with this concept. :smile:

1 Like

Er. In my own code, I do it like this: (pseudo code, I’m on mobile)

Mouse.Button1Down:Connect(function()
if not LMBDown then
LMBDown = true
end
--> later in the same function...
while LMBDown do 
task.wait()
--> Whatever else...
end
end)

Mouse.Button1Up:Connect(function()
if LMBDown then
LMBDown = false
end
end)
-- LocalScript
local state = false
UIS.InputBegan:Connect(function(input)
    if input.KeyCode ~= input.KeyCode.E then return end
    if state == false then
        Remote:FireServer(true)
    end
    state = true

    local inputend_conn
    inputend_conn = UIS.InputEnded:Connect(function(input)
        if input.KeyCode ~= input.KeyCode.E then return end
        inputend_conn:Disconnect()
        if state == true then
            task.wait() -- impotant
            Remote:FireServer() -- nil
        end
        state = false
    end)
end)

Now, in the ServerScriptService:

-- ServerScript
Remote.OnServerEvent:Connect(function(player, state)
    print(state) -- for debuging
    if not state then return end -- yes, it will work

    local cancel = false
    local cancel_conn = Remote.OnServerEvent:Connect(function(_player, _state)
        if _player ~= player then return end
        if _state == state then return end
        cancel_conn:Disconnect()
        cancel = true
        print("sucess")
    end)

    local timer = 0 -- for safety use other condition too
    repeat
        print("That was easy.")
        timer += 0.01
        task.wait(0.01)
    until cancel == true or timer == 3
    timer = 0
    cancel_conn:Disconnect()
end)

Your output should be:

true
sucess
nil/false

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.