How to check if a certain part is in an object

im trying to do a effect system where if you touch a part it gives you poison but if you already have poison it doesn’t do anything, but it doesn’t work and gives the error “attempt to index nil with ‘PlayerGui’”
this is my code

spawn(function()
	script.Parent.BloodP.CFrame = script.Parent.CFrame * CFrame.new(0, 2, 0)
	while true do
		wait(0)
		script.Parent.BloodP.Touched:Connect(function(hit)
			if hit.Name == "HumanoidRootPart" then
				local player = game.Players:GetPlayerFromCharacter(hit.Parent)
				
				local poison = game.Players:FindFirstChild(player).PlayerGui.ScreenGui["Buffs/Debuffs"]:FindFirstChild("Poison")
				if poison then

				else
					local Poison = game.ReplicatedStorage["Buff/Debuff"]:Clone()
					Poison.Parent = game.Players:FindFirstChild(player).PlayerGui.ScreenGui["Buffs/Debuffs"]
					Poison.Name = "Poison"
					Poison.BDtext.Text = "Poison"
					Poison.time.Value = 5
					Poison.amount.Value = 1
				end
			end
		end)
	end
end)
1 Like

I got it to give poison, but now the poison is given once but doesn’t give it again once the poison gui is destroyed (gui destroys itself)

spawn(function()
	script.Parent.BloodP.CFrame = script.Parent.CFrame * CFrame.new(0, 2, 0)
	while true do
		wait(0)
		script.Parent.BloodP.Touched:Connect(function(hit)
			if hit.Name == "HumanoidRootPart" then
				local player = game.Players:GetPlayerFromCharacter(hit.Parent)
				
				if player.PlayerGui.ScreenGui["Buffs/Debuffs"]:FindFirstChild("Poison") then

				else
					local Poison = game.ReplicatedStorage["Buff/Debuff"]:Clone()
					Poison.Parent = player.PlayerGui.ScreenGui["Buffs/Debuffs"]
					Poison.Name = "Poison"
					Poison.BDtext.Text = "Poison"
					Poison.time.Value = 5
					Poison.amount.Value = 1
				end
			end
		end)
	end
end)
1 Like

Please remove the Touched connection from the loop.
Please don’t use spawn anymore: it’s deprecated. Use task.spawn instead.
Please don’t use wait anymore: it’s deprecated. Use task.wait instead.
Instead of doing if (condition) else to check if a condition is not true, use if not (condition) instead.
After you do this we can fix the underlying issue in the logic, since it will be more readable.

1 Like

Also wait(0) is useless, empty it like this: wait() or use task..

1 Like

You shouldn’t put the .Touched connection in the loop, it’s not needed and might be why your script is not working properly.

local BloodP = script.Parent.BloodP
BloodP.CFrame = script.Parent.CFrame * CFrame.new(0, 2, 0)
BloodP.Touched:Connect(function(hit)
	if hit.Name == "HumanoidRootPart" then
		local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		if player then
			local buffs = player.PlayerGui.ScreenGui["Buffs/Debuffs"]
			
			if not buffs:FindFirstChild("Poison") then
				local Poison = game.ReplicatedStorage["Buff/Debuff"]:Clone()
				Poison.Parent = buffs
				Poison.Name = "Poison"
				Poison.BDtext.Text = "Poison"
				Poison.time.Value = 5
				Poison.amount.Value = 1
			end
		end
	end
end)

The while loop clones the Poison debuff too many times, probably causing ahh behavior. Remove the while loop.

still doesn’t work for it. just as a extra little bit that might change it, the part is actually a trail part that is cloned into the workspace under the player and would probably overlap with other copies of it.

The issue is that GetPlayerFromCharacter already gets the player object—you don’t need to use game.Players:FindFirstChild(player).