How To Check What Parts Are Touching Another Part

So this may sound oddly specific but is there a way to check all the parts that have touched a part, and then do something with it? I don’t want it to check if a PLAYER has checked it, rather just a part. In this case, named flame.

This is what I currently have now. I’ve tried to mess around with part:GetTouchingPartrs() but it hasn’t worked for me. I’m also still kinda new to coding so tell me if there’s any issues or stuff

local part = script.Parent

part.Touched:Connect(function(Hit)	
	if Hit.Name == "Flame" then
		print("TNT has touched the flame!")
		local forcefield = Instance.new("ForceField")
		local explosion = Instance.new("Explosion")
		explosion.Position = part.Position
		explosion.Parent = game.Workspace
		explosion.BlastRadius = 100
		explosion.BlastPressure = 0
		explosion.DestroyJointRadiusPercent = 0
		forcefield.Position = part.Position
		part:Destroy()
	end
end)

Thanks!

Does GetPartsInPart cover your requirements? So long as you know when you need to check for collisions, this would likely be a better solution than a Touched event.

1 Like

East98’s solution is likely what you meant, but in case “check all the parts that have touched a part” means to keep track of every part that has ever touched something rather than to figure out what is touching at that very moment, I think there’s little you could do outside of keeping a table and just adding parts onto it through the touched event.

With the code you’ve provided, it should be as simple as adding a table and table.insert right before you destroy the part.

Sorry for the late response, but what do you mean when you say that I need to know when to check for collisions? This is what I’ve tried, again I’m still kinda new to coding so I’m sure something here’s wrong, and it is printing “It happened,” output isn’t giving me anything else.

local part = script.Parent

part.Touched:Connect(function(Hit)	
	print("It happened")
	for i, v in pairs(game.Workspace:GetPartsInPart(part)) do
	 if v.Name == "Flame" then
		print("TNT has touched the flame!")
		local forcefield = Instance.new("ForceField")
		local explosion = Instance.new("Explosion")
		explosion.Position = part.Position
		explosion.Parent = game.Workspace
		explosion.BlastRadius = 100
		explosion.BlastPressure = 0
		explosion.DestroyJointRadiusPercent = 0
		forcefield.Position = part.Position
		part:Destroy()
	 end
	 end
end)


I say “when” meaning at what point in time do you want to be able to check for overlapping parts? Should this be checked every few seconds or possibly every frame? Should it only be checked after a specific event takes place?

The method GetPartsInPart is a spatial query method; It checks for intersecting parts when you call the method. Currently, the code you provided calls GetPartsInPart after the Touched event is triggered. This is currently your when. As I’m not sure exactly what you’re trying to accomplish, I can’t really say whether this is the right approach or not.

Also, when using GetPartsInPart you should be passing a second argument that is an OverlapParams. OverlapParams need to be created using a specific constructor and has properties that determine how a spatial query will operate. You’ll likely want to set at least the following:

--Create a new OverlapParams object
local myParams = OverlapParams.new()
--An array of objects (including any descendants) to be either included or excluded from the query depending on FilterType
myParams.FilterDescendantsInstances = {workspace}
--The other option is Enum.RaycastFilterType.Exclude, however it is less common
myParams.FilterType = Enum.RaycastFilterType.Include
--This will determine the maximum number of parts to be returned by the query
myParams.MaxParts = 10 

local part = script.Parent
local collisionList = workspace:GetPartsInPart(part, myParams)

i believe

part:GetTouchingParts()

also works, but i have not tested if you can use the same paramaters

The documentation on GetTouchingParts states that GetPartsInPart is a modern option with more flexibility. It should basically be assumed that GetPartsInPart should be used in any new work.

ah that makes sense, i will probably have to update some of my older scripts then.
sorry for the slight misinfo

GetPartsInPart might not be a perfect replacement for GetTouchingParts.
The latter isn’t documented too well on what “physically interacting” means. If we go off .Touched events, then it’s reliant on clients sending touch data, which might be better for latency/desynchronization reasons, as GetPartsInPart is a spatial query, which takes no input from clients.

I’m still new so I’m not familiar with everything you’re talking about, but this is what I’ve got.

local part = script.Parent
--Create a new OverlapParams object
local myParams = OverlapParams.new()
--An array of objects (including any descendants) to be either included or excluded from the query depending on FilterType
myParams.FilterDescendantsInstances = {workspace}
--The other option is Enum.RaycastFilterType.Exclude, however it is less common
myParams.FilterType = Enum.RaycastFilterType.Include
--This will determine the maximum number of parts to be returned by the query
myParams.MaxParts = 10 

local collisionList = workspace:GetPartsInPart(part, myParams)

part.Touched:Connect(function(Hit)	
	print("It happened")
	for i, v in pairs(collisionList) do
	 if v.Name == "Flame" then
		print("TNT has touched the flame!")
		local forcefield = Instance.new("ForceField")
		local explosion = Instance.new("Explosion")
		explosion.Position = part.Position
		explosion.Parent = game.Workspace
		explosion.BlastRadius = 100
		explosion.BlastPressure = 0
		explosion.DestroyJointRadiusPercent = 0
		forcefield.Position = part.Position
		part:Destroy()
	 end
	 end
end)

It IS firing, however it only fires when the player touches it and nothing else. Not if it’s an npc walking on it, a part dropping on it, etc. The goal is for it to activate when a part touches it, see what parts touched it, look through those parts and see if they have properties (the name being “Flame” in this case.)

I may be a little confused on what exactly you’re trying to do. If you could just explain what you want to happen, I may be able to help more.
If all you want is for some code to run when a Part comes into contact with another Part (as a result of physical movement) then all you need to do is establish a connection to a Touched event, like it appears you are doing.

local part = script.Parent
part.Touched:Connect(function(otherPart) --otherPart is the Part than collided with `part`
   --Code located here will run every time a Part touches `part`
end

I’ll explain it more thoroughly;

What I want is that when a part is touched by any part, not just a player, it checks what touched it, then, in this circumstance, it looks to see if the part’s name is “Flame”, to which if it is then it does the rest, otherwise does nothing.

So I guess something like this:

local part = script.Parent
part.Touched:Connect(function(otherPart) --Part is touched
   if otherPart.Name == "Flame" then -- Sees if the part that touched it's name is Flame
      	print("TNT has touched the flame!") -- Here is where it would make an explosion occur
		local forcefield = Instance.new("ForceField")
		local explosion = Instance.new("Explosion")
		explosion.Position = part.Position
		explosion.Parent = game.Workspace
		explosion.BlastRadius = 100
		explosion.BlastPressure = 0
		explosion.DestroyJointRadiusPercent = 0
		forcefield.Position = part.Position
		part:Destroy()
    end
end) -- If it didn't have the name "Flame" then it would do nothing, and check any other parts that touched it.
local testPart = workspace:WaitForChild("PartC")

for _, part in ipairs(testPart:GetTouchingParts()) do
	print(testPart.Name, "is touching", part.Name)
end
2 Likes

Yeah, the Touched event will fire for every Part that touched the Part the event is connected to. Could your issue perhaps be that you’re destroying the Part that you connected the Touched event to?

--The final line inside the conditional:
part:Destroy()
--By calling the line above, `part` is destroyed and the Touched event is disconnected
--Did you possibly mean:
otherPart:Destroy() --This is the part that you tested to see if it's Name is "Flame"

I tried just getting rid of everything but the print message, and nothing printed no matter what touched it. The :Destroy() is there just to make the explosion happen, but the forcefield that gets applied would save it from being actually destroyed.

after putting this into a .touched function it worked, thank you