Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by 5 years ago

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?

0
basically just add a touchended event BFFperson32 -6 — 5y

3 answers

Log in to vote
0
Answered by 5 years ago

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

0
Whilst I would do this, I'm afraid this wouldn't work because there would be multiple people being affected here. CyroStorms 4 — 5y
Ad
Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

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: [email protected]

    # 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.

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. CyroStorms 4 — 5y
Log in to vote
0
Answered by 5 years ago
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)

Answer this question