Why is .Touched not firing with Heartbeat?

  1. What do you want to achieve? Keep it simple and clear!
    My gun fires bullets and they should destroy themselves when they collide with another part and also destroy themselves after they havent hit anything after 5 seconds/

  2. What is the issue? Include screenshots / videos if possible!
    Before adding my heartbeat function the bullets destroyed themselves upon a collision but when I tried to use heartbeat to make them destroy themselves after 5 seconds passed they ignored collisions and only destroyed themselves after 5 seconds.

It seems to not destroy when being fired at the baseplate but when being fired at another character/NPC they do get destroyed.

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    Ive tried using wait but that didnt work.
local bullet = script.Parent
local now = tick()
--print("Bullet instantiated")
bullet.Touched:Connect(function(hit)
	--print("Hit something "..hit.Name)
	if hit.Parent:FindFirstChild("Humanoid") then
		local humanoid = hit.Parent.Humanoid
		humanoid.Health -= 10
		bullet:Destroy()
	elseif (hit.Name == "Bullet30" or "Bullet120") then
		return
	else
		bullet:Destroy()
	end
end)

game:GetService("RunService").Heartbeat:Connect(function()
	--print(now - tick())
	if tick() - now >= 5 then
		
		bullet:Destroy()
	end
end)

what happens if u put the touched function in the heartbeat function

That does nothing but additional resources taken.

For the @OP, does this print statement gets fired?

Oh yeah, I commented that out for better performance but yes it gets fired. It does detect if it hits something. It detects if it hits the baseplate but for some reason it just doesn’t delete itself… It used to delete itself before the heartbeat was added.

I mean, there is a simpler way to do this, and that’s with DebrisService.

At the top of the script, do this:

game:GetService("Debris"):AddItem(bullet, 5)

(It will automatically destroy itself after 5 seconds.)

Another thing to say is that I really do not reccomend using anything related to Touches, as an exploiter could enlarge bullet hitboxes; but for now, .Touched should work.

Oh thanks, I didn’t know that existed. Couldn’t find anything like that anywhere. But it didnt help in making it destroy itself in a collision.

bullet.Touched:Connect(function(hit)
	--print("Hit something "..hit.Name)
	if hit.Parent:FindFirstChild("Humanoid") then
		local humanoid = hit.Parent.Humanoid
		humanoid.Health -= 10
		bullet:Destroy()
	else
        if not (hit.Name == "Bullet30" or "Bullet120") then
		    bullet:Destroy()
        end
	end
end)

Because your running them at separates times in the code.

It still goes right through the baseplate…

Looks like I managed to fix it myself by doing this

local bullet = script.Parent
local now = tick()
--print("Bullet instantiated")
game:GetService("Debris"):AddItem(bullet,5)
bullet.Touched:Connect(function(hit)
	print("Hit something "..hit.Name)
	if hit.Parent:FindFirstChild("Humanoid") then
		print("Hit someone")
		local humanoid = hit.Parent.Humanoid
		humanoid.Health -= 10
		bullet:Destroy()
	else
		print("Hit something else "..hit.Name)
		if (hit.Name == "Bullet30" or hit.Name == "Bullet120") then
			--print("Hit something that wasnt a bullet")
			--bullet:Destroy()
			return
		end
		bullet:Destroy()
	end
end)

Looks like the or statement wasnt complete

But new problem how can I make it so that the bullets dont detect collisions with each other?

This was solved but I’ll point out the error so it doesn’t happen again.
Look in the else section of the Touched if statement.

...
elseif (hit.Name == "Bullet30" or "Bullet120")
...

The issue is that “or” and “Bullet120” after that.

You cannot compound that check, you must do this:

(hit.Name == "Bullet30" or hit.Name == "Bullet120")

The reason it wasn’t destroying was because

or "Bullet120"

is truthy, meaning it’ll always be true since “or” expects another conditional after it, otherwise it just accepts that value as the result, and

if "Bullet120" then
  print("True")
end

Will always print true.

1 Like

Much appreciated for clearing that up, I can be a bit stupid sometimes heh

1 Like