Why wont this heal the player?

Im trying to create a mine, that if stepped on heals the player. But for some reason the script wont work.

Script
while wait(3) do
	--Variables
	local number1 = math.random(-50,0)
	local number2 = math.random(-50,0)
	local Mine_Model_2 = Mine_Model:Clone()
	--Setting the mines position 
	Mine_Model_2.Activator.Position = Vector3.new(number1, 0.15,number2)
	Mine_Model_2.Base.Position = Vector3.new(number1, 0.05,number2)
	Mine_Model_2.Parent = workspace --Same simplification as line 1 but with game.Workspace
	game.Debris:AddItem(Mine_Model_2, 5)  --Deletes the part after 3 seconds, replaces the Destroy() function
	
	local Activator = Mine_Model_2:WaitForChild("Activator")
	
	Activator.Touched:Connect(function(hit)
		--Heal
		
		
		local sound = script:WaitForChild("Heal Sound")		
		local hitParent = hit.Parent
        if hitParent.Name == "Workspace" then return end

local humanoid = hitParent:WaitForChild("Humanoid")
		print(hitParent.Name.."_Has Healed!")
		print(humanoid.Health.."_<_"..humanoid.MaxHealth)
		print(hit, hitParent)
		if humanoid then
			if humanoid.Health <= humanoid.MaxHealth then
				sound:Play()
				humanoid.Health = humanoid.Health + 10
			end
		end
	end)
end

The only error i received from the output is " 23:16:49.036 Infinite yield possible on 'Workspace:WaitForChild("Humanoid")' - Studio

I tried fixing it by writing “if hitParent.Name == "Workspace" then return end” but that didnt work

Help is greatly appreciated, thank you for your time :smiley:

the hit part can be just a part and not Character

1 Like

First off there’s a few things I want to mention

  1. Do not use :Connect()'s on often happening events in a while loop, this causes it to spawn often and things will then happen more often than you want them to
  2. You didn’t check whether the thing that touched it is a bodypart, the activator got touched by a part inside workspace and its parent is workspace, and obviously it can’t find a “Humanoid” directly inside workspace!
2 Likes

Thank you for telling me! although im confused on what would i use in replace of connect

Would i use

if hit:IsA("BasePart")

?

local sound = script:WaitForChild("Heal Sound")
local Mine_Model = nil

while task.wait(3) do
	--Variables
	local number1 = math.random(-50,0)
	local number2 = math.random(-50,0)
	local Mine_Model_2 = Mine_Model:Clone()
	--Setting the mines position 
	Mine_Model_2.Activator.Position = Vector3.new(number1, 0.15,number2)
	Mine_Model_2.Base.Position = Vector3.new(number1, 0.05,number2)
	Mine_Model_2.Parent = workspace --Same simplification as line 1 but with game.Workspace
	game.Debris:AddItem(Mine_Model_2, 5)  --Deletes the part after 3 seconds, replaces the Destroy() function
	local Activator = Mine_Model_2:WaitForChild("Activator")
	Activator.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild("Humanoid") then
			local humanoid = hit.Parent:WaitForChild("Humanoid")
			if humanoid then
				sound:Play()
				humanoid.Health += 10
			end
		end
	end)
end

You can use a connect, you’ll just need to disconnect it, you can do so like this:

local connection

connection = Part.Touched:Connect(function()
   -- the function in here obviously
end)


-- once you want to stop it, you can run the following
connection:Disconnect()
-- for this case its probably easier if you declare 'connection' above the while loop
-- you can then access it from outside the while loop, or even from within the next while loop
1 Like

Ignore this post for the time.

1 Like
Activator.Touched:Connect(function(hit)
		--Heal
		if hit and hit.Parent then
           local humanoid = hit.Parent:FindFirstChild("Humanoid")
           if humanoid ~= nil and humanoid.Health > 0 then 
              -- do some stuff
           end
        end
	end)

don’t forget to add statements to confirm if it’s an actual humanoid or not

1 Like

so something like

connection = Activator.Touched:Connect(function(hit)
		--Heal
		local sound = script:WaitForChild("Heal Sound")		
		local hitParent = hit.Parent
		if hitParent.Name == "Workspace" then return end
		local humanoid = hitParent:WaitForChild("Humanoid")
		print(hitParent.Name.."_Has Healed!")
		print(humanoid.Health.."_<_"..humanoid.MaxHealth)
		print(hit, hitParent)
		if humanoid then
			if humanoid.Health <= humanoid.MaxHealth then
				sound:Play()
				humanoid.Health += 10
			end
		end
	end)



while true do
    --stuff
    connection:Disconnect(
end

No, more something like:

local connection


while wait(3) do
    if connection then
       connection:Disconnect()
    end
	--Variables
	local number1 = math.random(-50,0)
	local number2 = math.random(-50,0)
	local Mine_Model_2 = Mine_Model:Clone()
	--Setting the mines position 
	Mine_Model_2.Activator.Position = Vector3.new(number1, 0.15,number2)
	Mine_Model_2.Base.Position = Vector3.new(number1, 0.05,number2)
	Mine_Model_2.Parent = workspace --Same simplification as line 1 but with game.Workspace
	game.Debris:AddItem(Mine_Model_2, 5)  --Deletes the part after 3 seconds, replaces the Destroy() function
	
	local Activator = Mine_Model_2:WaitForChild("Activator")
	
	connection = Activator.Touched:Connect(function(hit)
		--Heal
		
		
		local sound = script:WaitForChild("Heal Sound")		
		local hitParent = hit.Parent
        if hitParent.Name == "Workspace" then return end

local humanoid = hitParent:WaitForChild("Humanoid")
		print(hitParent.Name.."_Has Healed!")
		print(humanoid.Health.."_<_"..humanoid.MaxHealth)
		print(hit, hitParent)
		if humanoid then
			if humanoid.Health <= humanoid.MaxHealth then
				sound:Play()
				humanoid.Health = humanoid.Health + 10
			end
		end
	end)
end
1 Like
Activator.Touched:Connect(function(hit)
	local Character = hit:FindFirstAncestorWhichIsA("Model")
	if Character then
		local Humanoid = Character:FindFirstChild("Humanoid")
		if Humanoid then


			--Heal
			local sound = script:WaitForChild("Heal Sound")	
			print(Character.Name.."_Has Healed!")
			print(Humanoid.Health.."_<_"..Humanoid.MaxHealth)
			print(hit, Character)
			if Humanoid.Health <= Humanoid.MaxHealth then
				sound:Play()
				Humanoid.Health = Humanoid.Health + 10
			end


		end
	end
end)

Better way to check if hit is a descendant of a Model, which could potentially be a character. No need for multiple ‘hit.Parent.Parent’ or whatever.

1 Like
local sound = script:WaitForChild("Heal Sound")
local Mine_Model = nil --reference mine_model here
local connection = nil

while task.wait(5) do
	local number1 = math.random(-50,0)
	local number2 = math.random(-50,0)
	local Mine_Model_2 = Mine_Model:Clone()
	Mine_Model_2.Activator.Position = Vector3.new(number1, 0.15, number2)
	Mine_Model_2.Base.Position = Vector3.new(number1, 0.05, number2)
	Mine_Model_2.Parent = workspace
	game.Debris:AddItem(Mine_Model_2, 4.5)
end

workspace.DescendantAdded:Connect(function(descendant)
	if descendant.Name == "Activator" then
		connection = descendant.Touched:Connect(function(hit)
			if hit.Parent:FindFirstChild("Humanoid") then
				local humanoid = hit.Parent:WaitForChild("Humanoid")
				if humanoid then
					sound:Play()
					humanoid.Health += 10
				end
			end
		end)
	end
end)

workspace.DescendantRemoving:Connect(function(descendant)
	connection:Disconnect()
end)

Make it so that the loop isn’t repeating more frequently than the frequency at which new mines are being created.

Alright! Thank you!

How would i check if the hitParent is a bodypart? Would i use hitParent:IsA("BasePart")?

1 Like

if hit.Parent:FindFirstChild("Humanoid")

if hitParent:IsA("Model") and hitParent:FindFirstChild("Humanoid") then
   -- its a player 
end
1 Like

But what if the object that touches the mine doesnt have a model? (Like the players right leg)

The ancestor is a parent, or a parent of a parent, or even further, the leg’s first model ancestor is the character object

1 Like

OHHH, i read “Ancestor” as child. Thats my bad :sweat_smile:

FindFirstAncestorWhichIsA finds the first ancestor of a particular class, the left leg of a player’s character model has its first ancestor which is a model be the player’s character model itself.

1 Like