Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How do I break a while loop after a brick has stopped touching a part?

This is the code we're dealing with:

HitBox.Touched:connect(function(Brick)
	Touching = true
	while Mode.Value == "Gas" and Touching do
		if Brick.Name == "Torso" and Brick.Parent:FindFirstChild("Humanoid") then
			Brick.Parent.Humanoid.Health = Brick.Parent.Humanoid.Health - 1
		end
	wait (0.1)
	end
end)

I've tried to place the .TouchEnded event pretty much everywhere and I don't know a good way to check if a brick has stop touching a brick upon each iteration of the while loop then change Touching to false.

Can you help?

1 comment

0

basically just add a touchended event

3 answers


HitBox.Touched:connect(function() Touching = true end) HitBox.TouchEnded:connect(function() Touching = false end

Touching.Changed:connect(function()

end)

while Touching = true do insert script here end

1 comment

0

Whilst I would do this, I'm afraid this wouldn't work because there would be multiple people being affected here.

I would suggest a game logic strategy for updating all queuing humanoids every so often. That way there's no need to worry about disconnecting and reconnecting events at an unnecessarily high rate, or breaking loops. Here's my personal tested solution to your problem...

--[[
	# Author: William J. Horn (ScriptGuider)
	# Contact: willisoftencoding@gmail.com
	
	# Efficiency test logs:
		test 1: 1    --   1.5%  CPU usage
		test 2: 0.4% --   1%    CPU usage
		test 3: 0    --   0.3%  CPU usage
--]]

-- Tested in an empty place using the baseplate as the part
local part = workspace:WaitForChild("Baseplate")
local tableRemove = table.remove

local function removeFromQueue(queue, key)
	for i = 1, #queue do
		if queue[i] == key then
			tableRemove(queue, i)
		end
	end
end

local function isInQueue(queue, key)
	for i = 1, #queue do
		if queue[i] == key then
			return true
		end
	end
end

local function addToQueue(queue, entry)
	queue[#queue + 1] = entry
end

local damageQueue = setmetatable({}, {
	__index = {
		add = function(self, human, hit)
			local entry = self:get(human)
			if entry and not isInQueue(entry[1], hit) then
				addToQueue(entry[1], hit)
			elseif not entry then
				addToQueue(self, {{hit}, human})
			end
		end,
		get = function(self, human)
			for i = 1, #self do
				if self[i][2] == human then
					return self[i]
				end
			end
		end,
		remove = function(self, human, hit)
			local entry = self:get(human)
			if entry then
				removeFromQueue(entry[1], hit)
				if #entry[1] == 0 then
					for i = 1, #self do
						if self[i][2] == human then
							tableRemove(self, i)
						end
					end
				end
			end
		end,
		step = function(self, damage)
			for i = 1, #self do
				local human = self[i][2]
				if human.Health > 0 then
					self[i][2]:TakeDamage(damage)
				end
			end
		end
	}
})

part.Touched:Connect(function(hit)
	local human = hit.Parent:FindFirstChildOfClass("Humanoid")
	if human then 
		damageQueue:add(human, hit) 
	end
end)

part.TouchEnded:Connect(function(hit)
	local human = hit.Parent:FindFirstChildOfClass("Humanoid")
	if human then 
		damageQueue:remove(human, hit) 
	end
end)

-- Game logic
while wait(0.1) do
	-- damage queue step update dealing 1 damage
	damageQueue:step(1)
end

If you have any questions, just let me know.

1 comment

0

Thank you for the awfully complex reply, but by the time I had read this, I had a much more simple solution. Thanks regardless.

HitBox.Touched:connect(function()
	while Mode.Value == "Gas" and Enabled.Value do
		for _, Brick in pairs (HitBox:GetTouchingParts()) do
			if Brick.Name == "Torso" and Brick.Parent:FindFirstChild("Humanoid") then
				Brick.Parent.Humanoid.Health = Brick.Parent.Humanoid.Health - 1
			end
		end
		wait (0.1)
	end
end)

This discussion is preserved as it was. New answers, comments, and votes are closed.