Break Loop when remote event fires

When remote event 1 fires, it starts a loop, when remote event two fires, I need that loop to stop.
What solutions have you tried so far?** Did you look for solutions on the Developer Hub?
I have tried to do

if game.ReplicatedStorage.Remotetwo.OnClientEvent then break end

I have also heard of disconnect and using a variable to break the loop. Indeed the variable method did work but I removed it as I am uncertain that it would work when multiple people need to use the same remote event. As the loop may need to break for one person, and one person only. If I use the variable method, I am fearful that It would break all loops for everyone. Indeed I don’t know if this method using a remote event will break all loops for everyone or not, but I hope it will work.

If you want to know what the architecture of the scripts looks like its like this:


If the recivers recive a signal that originated from their tandem main script, it is blocked as the main script already does what the signal sent out is telling the other scripts to do.
The Server does not do anything, it merely does :FireAllClients OnServerEvent.
I hope this illustrates that there cant be 1 variable that controls if the loop, as if red changes that variable, It would also block the loop for blue and orange. I dont know if remote event break will do the same, but I dont think it will.

I hope this is all clear, to reiterate. I want to break a loop when a remote event is fired. And I probably cant use a variable local to the receiver script. Another drawing to illustrate what I want to do:


In this image, the different colors are different remote events, instead of in the previous one, where the different colors are different origins of the signals.

1 Like

If I understand what you are trying to do, then there are two ways you could do this.

The first method, just using a break variable. A very simple example, but just shows the idea:

local remoteEvent = game.ReplicatedStorage.RemoteEvent -- Get the remote event

local loop = true

remoteEvent.OnClientEvent:Connect(function()
  loop = false -- Indicate the loop should stop
end)

-- Loop while the `loop` variable is true
while loop do
  -- Loop logic here

  wait()
end

A second method would be to wrap the loop in a coroutine and then cancel it when you want the loop to stop. You can read up on it here:

Hope this helps a bit! Let me know if you have any other questions. Good luck! :slight_smile:

2 Likes

I don’t know how to use the coroutines, and I am getting nowhere with the wrapping function in the documentation. I think its not applicable to this scenario. I also don’t want to use the loop = true thing as I worry that will stop the loop for everyone. I say everyone as I noticed that the remote event will run two instances of the function when called twice, I worry that if one person changes the loop to false, person two will also get blocked. I will try to explain it again with the actual code this time.

game.ReplicatedStorage.StanceReseter.OnClientEvent:Connect(function(Player,Humanoid,Root,LHip,RHip)
	if TruePlayer ~= Player then
		Humanoid.CameraOffset = StanceOffset[1]
		LHip.C0 = CF(-1, -1, 0) * CFANG(0, RAD(-90), 0)
		LHip.C1 = CF(-0.5, 1, 0) * CFANG(0, RAD(-90), 0)
		RHip.C0 = CF(1, -1, 0) * CFANG(RAD(-180), RAD(90), 0)
		RHip.C1 = CF(0.5, 1, 0) * CFANG(RAD(-180), RAD(90), 0)
		Root.C0 = CFANG(RAD(-90), 0, RAD(180))
	end
end)

game.ReplicatedStorage.Stancer.OnClientEvent:Connect(function(Player,Name,Humanoid,Root,StanceChangeSpeed,Stance,PreviousStance,Neck,TCFM)
	if TruePlayer ~= Player then
		local PreviousOffset = Humanoid.CameraOffset
		local PreviousRootP = Root.C0.p
		local PreviousNeckP = Neck.C0.p
		for X = 0, 90, 1.5 / StanceChangeSpeed do
			local Alpha = Sine(X)
			Humanoid.CameraOffset = PreviousOffset:lerp(StanceOffset[Stance+1], Alpha)
			if Name == "Stand" then
				if Stance ~= 0 then break end
				Root.C0 = CF(PreviousRootP:lerp(VEC3(), Alpha)) * CFANG(RAD(-90), 0, RAD(180))
				Neck.C0 = CF(PreviousNeckP:lerp(VEC3(0,1.5,0), Alpha))
			elseif Name == "Crouch" then
				if Stance ~= 1 then break end
				Root.C0 = CF(PreviousRootP:lerp(VEC3(0, -1, 0), Alpha)) * CFANG(RAD(-90), 0, RAD(180))
				if PreviousStance == 2 then
					Neck.C0 = CF((PreviousNeckP*VEC3(1,1,-1)):lerp(VEC3(0,1.5,0), Alpha))
				else
					Neck.C0 = CF((PreviousNeckP):lerp(VEC3(0,1.5,0), Alpha))
				end
			elseif Name == "Prone" then
				if Stance ~= 2 then break end
				Root.C0 = CF(PreviousRootP:lerp(VEC3(0, -2.5, 1), Alpha)) * CFANG(RAD(180), 0, RAD(180))
				Neck.C0 = CF((PreviousNeckP*VEC3(0,0,0)):lerp(VEC3(0, 1, 1), Alpha)) * CFANG(RAD(90), 0, 0)
			end
			RS:wait()
		end
	end
end)

and

game.ReplicatedStorage.Animator.OnClientEvent:Connect(function(Player, Joint, Jparent, NewC0, NewC1, Message, Duration,Gun_Ignore)
	local Alpha
	if Message == "Sine" then
		Alpha = function(X) --Sine standin
			return SIN(RAD(X))
		end
	else
		Alpha = function(X) --Linear standin
			return (X / 90)
		end
	end
	if Player ~= game.Players.LocalPlayer and Joint ~= nil then
		if Joint == "RightGrip" or Joint == "Left Hip" or Joint == "Right Hip" then
			Joint = Player.Character[Jparent][Joint]
		else
			Joint = Gun_Ignore.PlayerFolder[Jparent][Joint]
		end
		local TweenIndicator = nil --At the current moment, this is how the script determines whether the function is already tweening a joint
		local NewCode = math.random(-1e9, 1e9) --This creates a random code between -1000000000 and 1000000000
		if (not Joint:FindFirstChild("TweenCode")) then --If the joint isn't being tweened, then
			TweenIndicator = Instance.new("IntValue")
			TweenIndicator.Name = "TweenCode"
			TweenIndicator.Value = NewCode
			TweenIndicator.Parent = Joint
		else
			TweenIndicator = Joint.TweenCode
			TweenIndicator.Value = NewCode --If the joint is already being tweened, this will change the code, and the tween loop will stop
		end
		local MatrixCFrame = function(CFPos, CFTop, CFBack)
			local CFRight = CFTop:Cross(CFBack)
			return CF(
				CFPos.x, CFPos.y, CFPos.z,
				CFRight.x, CFTop.x, CFBack.x,
				CFRight.y, CFTop.y, CFBack.y,
				CFRight.z, CFTop.z, CFBack.z
			)
		end
		local LerpCF = function(StartCF, EndCF, Alpha)
			local StartTop = (StartCF * CFANG(RAD(90), 0, 0)).lookVector
			local StartBack = -StartCF.lookVector
			local EndTop = (EndCF * CFANG(RAD(90), 0, 0)).lookVector
			local EndBack = -EndCF.lookVector
			local StartPos = StartCF.p
			local EndPos = EndCF.p
			local NewCF = MatrixCFrame(
				StartPos:lerp(EndPos, Alpha),
				StartTop:lerp(EndTop, Alpha),
				StartBack:lerp(EndBack, Alpha)
			)
			return NewCF
		end
		local StartC0 = Joint.C0
		local StartC1 = Joint.C1
		local X = 0
		while true do
			local NewX = X + math.min(1.5 / math.max(Duration, 0), 90)
			X = (NewX > 90 and 90 or NewX)
			if TweenIndicator.Value ~= NewCode then break end --This makes sure that another tween wasn't called on the same joint
			if NewC0 then Joint.C0 = LerpCF(StartC0, NewC0, Alpha(X)) end
			if NewC1 then Joint.C1 = LerpCF(StartC1, NewC1, Alpha(X)) end
			if X == 90 then break end
			RS:wait() --This makes the for loop step every 1/60th of a second
		end
		if TweenIndicator.Value == NewCode then --If this tween functions was the last one called on a joint then it will remove the code
			TweenIndicator:Destroy()
		end
	end
end)

I will provide detailed explanations for what the code is doing if you want so. But here is what is important:
When Stancer is called while the stancer loop is playing, I need it to pause the loop. then create a new one. This prevents two loops being played on one person, which causes jittering. (will show if you want to see it)
If stancereseter is called then I need it to break the stancer loop and animator loop.
I tried having the loops in coroutines, but yielding them did not work. I will continue to work on this while I wait for your response. Hear from you soon! :slight_smile:

By adding a variable in the player, I can make the variable break loop method work like this:

game.ReplicatedStorage.StanceReseter.OnClientEvent:Connect(function(Player,Humanoid,Root,LHip,RHip)
	if TruePlayer ~= Player then
		Player.Character.Previoustance.Value = 0
		Humanoid.CameraOffset = StanceOffset[1]
		LHip.C0 = CF(-1, -1, 0) * CFANG(0, RAD(-90), 0)
		LHip.C1 = CF(-0.5, 1, 0) * CFANG(0, RAD(-90), 0)
		RHip.C0 = CF(1, -1, 0) * CFANG(RAD(-180), RAD(90), 0)
		RHip.C1 = CF(0.5, 1, 0) * CFANG(RAD(-180), RAD(90), 0)
		Root.C0 = CFANG(RAD(-90), 0, RAD(180))
	end
end)

game.ReplicatedStorage.Stancer.OnClientEvent:Connect(function(Player,Name,Humanoid,Root,StanceChangeSpeed,NewStance,Neck)
	if TruePlayer ~= Player then
		local PreviousStance = Player.Character.Previoustance.Value
		Player.Character.Previoustance.Value = NewStance
		local Stance = Player.Character.Previoustance.Value
		local PreviousOffset = Humanoid.CameraOffset
		local PreviousRootP = Root.C0.p
		local PreviousNeckP = Neck.C0.p
		for X = 0, 90, 1.5 / StanceChangeSpeed do
			local Alpha = Sine(X)
			Humanoid.CameraOffset = PreviousOffset:lerp(StanceOffset[Stance+1], Alpha)
			Stance = Player.Character.Previoustance.Value
			if Name == "Stand" then
				if Stance ~= 0 then break end
				Root.C0 = CF(PreviousRootP:lerp(VEC3(), Alpha)) * CFANG(RAD(-90), 0, RAD(180))
				Neck.C0 = CF(PreviousNeckP:lerp(VEC3(0,1.5,0), Alpha))
			elseif Name == "Crouch" then
				if Stance ~= 1 then break end
				Root.C0 = CF(PreviousRootP:lerp(VEC3(0, -1, 0), Alpha)) * CFANG(RAD(-90), 0, RAD(180))
				if PreviousStance == 2 then
					Neck.C0 = CF((PreviousNeckP*VEC3(1,1,-1)):lerp(VEC3(0,1.5,0), Alpha))
				else
					Neck.C0 = CF((PreviousNeckP):lerp(VEC3(0,1.5,0), Alpha))
				end
			elseif Name == "Prone" then
				if Stance ~= 2 then break end
				Root.C0 = CF(PreviousRootP:lerp(VEC3(0, -2.5, 1), Alpha)) * CFANG(RAD(180), 0, RAD(180))
				Neck.C0 = CF((PreviousNeckP*VEC3(0,0,1)):lerp(VEC3(0, 1, 1), Alpha)) * CFANG(RAD(90), 0, 0)
			end
			RS:wait()
		end
	end
end)

Thank you.

1 Like

I appreciate the powerpoint (my friend does also)

1 Like

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