How do I stop this if else statement from running both statements at once?

I am sorry if the title is really confusing but I had no clue how to word it.
Hi! I’ve ran into an issue with if statements and someone more experienced to take a look:

-- This is a code snippet, all of the functions work(ed) before I started checking if a player doesn't have a tool which leads me to believe my if statement is just not formulated right

Sensor.Touched:Connect(function(hit)
	if debounce == false then
		debounce = true

		if hit.Parent:FindFirstChildWhichIsA("Tool") then --Checks if a player has a tool
			if hit.Parent:FindFirstChild("Cheesebox") then --Checking for a specific item
				Cheese(game.Players:GetPlayerFromCharacter(hit.Parent), hit.Parent) --Function that applies a decal to a part and then DELETES the tool from the players inventory
			elseif hit.Parent:FindFirstChild("Pepperoni") then 
				Pepperoni(game.Players:GetPlayerFromCharacter(hit.Parent), hit.Parent)
			elseif hit.Parent:FindFirstChild("Sausages") then
				Sausages(game.Players:GetPlayerFromCharacter(hit.Parent), hit.Parent)
			elseif hit.Parent:FindFirstChild("Mushrooms") then
				Mushrooms(game.Players:GetPlayerFromCharacter(hit.Parent), hit.Parent)
			end
		elseif not hit.Parent:FindFirstChildWhichIsA("Tool") then -- Fires even if a player has a tool equipped, why?
			PickUp(game.Players:GetPlayerFromCharacter(hit.Parent), hit.Parent) --Function that copies properties of a model that are then copied onto a tool
		end
		
		wait(1)
		debounce = false
	end
end)

I tried formatting this in a lot of different ways (different order of conditions, spamming ifs, spamming elseifs without nesting them), including searching the forum but to no avail.
I thought it’s a weird timing issue because I am deleting items, so I tried adding wait()s in all sorts of places where I thought they’d make a difference but that hasn’t changed anything.

1 Like

Just to check, is ‘debounce’ ever declared outside of the function? If both the ‘if’ and ‘else’ statements are running at once - your function is being called twice.

If you touch the part with the tool hit.Parent will be the tool itself so maybe add not hit.Parent:IsA("Tool")

It is declared outside the function so I think that’s not the issue?

1 Like

I agree, but I wasn’t really sure how to do this, if you have any suggestions on how to make that more readable I’d love to hear it!

Do the functions just give you an item based on their function name?

No, I am simply checking if a player has an item with a specific name, I then run code to apply a decal to a part and the tool is deleted afterwards

Sorry, I haven’t clarified that, the part is being touched by a characters leg(s) hence the .Parent

Not a productive comment my dude…

@Lopatka if you do want to make this more efficient, this could be an alternative instead of having a separate function for each. Though it does not appear to be the source of your issue.

ApplyDecal(cheeseDecalId, game.Players:GetPlayerFromCharacter(hit.Parent), hit.Parent)
1 Like

Is it possible something besides the leg is hitting it (like a hat or tool, which is deeper down tree, or even a part in workspace/elsewhere touching it and since there is no Tool in workspace, it fires second condition)? Try adding an

if not game.Players:GetPlayerFromCharacter(hit.Parent) then return end

at the top. Otherwise… this should work, assuming the functions are doing as you expect!

7 Likes

The functions are doing what they should, just not when they should, if that makes sense? (I tried doing what you suggested and it didn’t help)
It’s this elseif not hit.Parent:FindFirstChildWhichIsA("Tool") then that’s giving me trouble. When the first if statement is true (a player has a tool equipped), the elseif runs anyway

try returning after every function

Try this:

local Debounces = {}
local Events = {
	["Cheesebox"] = Cheese,
	["Pepperoni"] = Pepperoni,
	["Sausages"] = Sausages,
	["Mushrooms"] = Mushrooms
}

local function GetPlayerFromObject(obj)
	for k,v in next, game:GetService("Players"):GetPlayers() do
		if not v.Character then
			continue
		end

		if obj:IsDescendantOf(v.Character) then
			return v
		end
	end
end

Sensor.Touched:Connect(function(hit)
	local Player = GetPlayerFromObject(hit) or error("sensor touched: failed to find player!") -- i did this because some parts might fire touched that are a descendant of a descendant of the character
	local Tool = Player.Character:FindFirstChildWhichIsA("Tool")
	
	Debounces[Player] = Debounces[Player] or os.time() - 50
	if os.time() - Debounces[Player] < 1 then -- i assumed you wanted multiple debounce times for every player
		return
	end

	if not Tool then 
		PickUp(Player, Player.Character)

		return -- stops everything below this from running
	end

	if Events[Tool.Name] then
		Events[Tool.Name](Player, Player.Character)
	end
end)

When I do that the functions just don’t run for some reason

And trying @0xA2CAD3’s solution unfortunately led to the same effect as my original code

Have you tried printing something in the else if, maybe some other part of your code or some other script is doing that?

Are you sure that there are not other objects named, Cheesebox, Pepperoni, Sausages or Mushrooms in the character

Me and @Naco88 managed to find and fix the issue. Turns out I was just not disconnecting previous events from a prompt istance that all of my functions relied on.
Thank you all for help though!

1 Like