"GetTouchingParts()" won't work (Previously titled: Identical NPC won't take damage)

I’m making a game with a flamethrower. The flamethrower has a Cone shaped hitbox in front of it. Using “GetTouchingParts()”, I’m able to detect which parts are touching that hitbox. If the parent is an NPC, then it’ll deal damage to it.
It easily deals damage to a Drooling Zombie, but my (as far as I can tell) identical custom NPC is seemingly invincible.
My custom NPC dies when it takes damage to a Linked Sword, however.

Custom NPC has it’s Torso, HumanoidRootPart, and Head set to “CanCollide = true”
So does the Drooling Zombie

Upon printing I’ve seen that the issue is that the “GetTouchingParts()” function doesn’t work on my custom NPC, but I can’t understand why. In fact, it works on literally no other parts besides the Drooling Zombie’s.

Any help is appreciated, if you need more info, feel free to ask.

1 Like

I think you’d need to clarify how your custom NPC is different. Is it client-sided?

“Animate” is the only LocalScript in my Custom NPC. The rest are Server Scripts.
Funnily enough, “Zombie” also has an “Animate” script, but it’s Server Sided. Also, Zombie had no PrimaryPart when I added it to the game. I had to add the Primary Part in myself.
I added Zombie’s “Animate” to my Custom NPC and removed my Custom NPC’s LocalScript but it had no effect.

Hi,

so your custom NPC has the same Parts like the zombie? Is it also a Mesh Character?

Can you maybe send the script that detects the collission using “GetTouchingParts()”?

Regarding the animate script: if putting the zombies Animate script wont work in your NPC then there might be an Issue with the Rig itself. Or the rigtypes are different (R6 and R15)

Try checking the server’s POV, your npc might only be moving on clientside

Just checked, it moves on the server.

My CustomNPC’s made out of BaseParts (Its the Female R6 rig) just like the Zombie and it has one mesh for the torso (the zombie has more meshes for its custom limbs)
I’ll send the entire script which finds the TouchingParts:

tool.Equipped:Connect(function()
	while wait(rate) do -- rate is a value that is 1/20
		local touching = cone:GetTouchingParts() -- returns table of parts that are CanCollide = true. My NPC and the Zombie all have their HRP, Head, and Torso set to CC true.
		print(touching)
		local parents = {} -- parents of those
		local dupeless = {} -- parents but w/o duplicates
		for i, v in pairs(touching) do
			if v.Parent:HasTag("enemy") then -- both npc's have this tag with correct capitalization
				table.insert(parents, v.Parent) 
			end
			print(parents)
			for i,v in pairs(parents) do
				if not table.find(dupeless, v) then -- removes dupes
					table.insert(dupeless,v)
				end
			end
			print(dupeless)
		end
		for i,v in pairs(dupeless) do
			local hum = v:FindFirstChildWhichIsA("Humanoid")
			local distance = (v.PrimaryPart.Position - script.Parent.Position).Magnitude
			local quo = distance/range
			dmg = maxDmg * (1-quo)
			hum:TakeDamage(dmg)
		end

When i print touching or any other table, it returns the parts of the zombie but not anything else in the workspace. Be it a random brick or my npc…

The table “Touching” only returns parts that are part of Drooling Zombie or its clones… nothing else. This is really weird! It doesn’t for the Classic Soldier, Rhtro Soldier, not Rthro Zombie, even when I give them the “enemy” tag

So if i understood it correct than you just want to deal damage to the npcs that have an ‘enemy’ tag when they touch the cone hitbox. Isnt your script a bit too complicated for such task? You could for example connect a touched event to the cone when the tool is equipped and find the humanoid and tag:

local touchConnection = nil
tool.Equipped:Connect(function()
     touchConnection = cone.Touched:Connect(function(hit)
          local character = hit.Parent
          if character and character:FindFirstChild("Humanoid") and character:HasTag("enemy") then
               local humanoid = character:FindFirstChild("Humanoid")
               humanoid:TakeDamage(10)
          end
     end)
end)

And when you are unequipping it you can disconnect the connection again to prevent memory overflow:

tool.Unequipped:Connect(function()
    if touchConnection then
        touchConnection:Disconnect()
        touchConnection = nil
    end
end)

If you wrote your script like that because you want any other specific things to archive besides the damage logic then it would help to explain it a bit further

Well, it seems the issue has to lie with the :HasTag() function. Is it capitalized correctly? Are you sure it’s the parent that’s tagged?

To be honest, I’ve never actually used, seen, or even heard of the tag system. I’ve just used ModuleScripts or attributes instead. ModuleScripts can have custom logic/functions, and attributes make for easy server → client communcation as well as being easy to debug. Not sure what tags have to offer.

Its from the CollectionService, :HasTag exists. But I just saw a mistake in my code, sorry for that. You gotta refer the Collectionservice and access the :HasTag from it in your if statement:

local CollectionService = game:GetService("CollectionService")
tool.Equipped:Connect(function()
     touchConnection = cone.Touched:Connect(function(hit)
          local character = hit.Parent
          if character and character:FindFirstChild("Humanoid")
                       and CollectionService:HasTag(character, "enemy") then
               local humanoid = character:FindFirstChild("Humanoid")
               humanoid:TakeDamage(10)
          end
     end)
end)

I’m guessing the cone part for your flamethrower is CanCollide = false.
Turn it to CanCollide = true and it should start detecting everything.

:GetTouchingParts() requires both the initial part (cone) and the touching part (everything else) to be CanCollide = true. If I remember correctly.

Question is: Why does :GetTouchingParts() work with the zombie then?
Well after digging around I can narrow it down to this portion of code:

leftHitConnect = model:FindFirstChild("Left Arm").Touched:connect(handleHit)
	rightHitConnect = model:FindFirstChild("Right Arm").Touched:connect(handleHit)

ModuleScript ROBLOX_ZombieAI, Line 342.

As far as I can tell, the zombie being able to trigger a Touched event will also cause :GetTouchingParts() to return a table with instances. This can be tested (and proven) by connecting a part to a .Touched event in a script and letting it “touch” (if falling straight through a noncollidable part can be considered touching) your cone (with the cone’s CanCollide = false).

So your solutions are (choose one):

  • Cone CanCollide = true
  • Connect every part in your game to a .Touched event
  • Use :GetPartsInPart() or some other alternative

Well at least based on what I figured, I’m not an expert in any of this.

1 Like

CanCollide true for a hitbox isnt a good idea since its a hitbox. You may collide with it yourself and the npc would be pushed away too if it touches it which we dont want. But youre right. :GetTouchingParts only works with CanCollide true

Hey, no, that won’t work. It’s a flamethrower so it has to take damage continuously while the mouse is being held down. This script is activated when the mouse is being held down.
From what I can tell, your script will deal 10 damage every time the NPC re-enters the Hitbox Cone. However, I need it to deal damage every time the NPC is inside said Hitbox Cone

Tags are nice, I like using them. Attributes are great for storing statistics, like “damage per second” or “top speed” etc.
Tags are like classification systems. Like “Herbivore”, “Enemy”, “Friend”
Yes, capitalization is correct, I must’ve checked that at least a hundred times by now!

This is really helpful, thanks.
So, for your first solution, as the guy above me said- It’s a hitbox. That’s totally impractical. However, it does work, which surprised me, because the description in Studio for the “:GetTouchingParts()” function said that it returns a table of the “CanCollide = True” parts that intersect with it, never specifying that the part looking for touchers must be CanCollide True.
The last one I’m unfamiliar with, I typed it into studio and said "GetPartsInPart() is not a valid member of MeshPart (MeshPart is probably not the Cone because the cone is named “Cone”). It didn’t even show up in the list when I typed “:Get”

Your third option worked. Thanks

Based on @Lleventyate’s information. I was able to fix this issue.

So, in my enemies folder, I made a script that loops through all the enemies (i, v in pairs) and added a touched function to all of them, like so:

for i, v in pairs(workspace.Enemies:GetChildren()) do
		local hitConn = v.Torso.Touched:Connect(function(hit)

		end)
end

If your Enemy is an R6, non-rthro character, it should now appear in the “GetTouchingParts()” table.

Why does this work?
Well, it’s detailed in @Lleventyate 's post. It’s above this one!

Thank you all!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.