Check if a part is still touching another part after touched event is called

How can I achieve this? Will I have to use region 3?

1 Like

Whenever I’ve had to do it, something like this worked. Your mileage may vary (but it should work unless the events fire out of order).

local mainPart = workspace.mainPart
local touchingParts = {}

mainPart.Touched:Connect(function(part)
	touchingParts[part] = true
end)

mainPart.TouchEnded:Connect(function(part)
	touchingParts[part] = nil
end)

if touchingParts[somePart] then
	-- code
end

BasePart:GetTouchingParts returns an array of parts that are touching.

1 Like

If I recall that only works with CanCollide as true (without an ugly hack).

How do I find and get a certain part in the array?

local main_part = ... -- the main part
local concerned_part = ... -- the part you want to know is touching the main part

local touching_parts = main_part:GetTouchingParts()

for i=1,#touching_parts do
    local part = touching_parts[i]
    if part == concerned_part then
        print("the concerned part is touching the main part")
        return true
    end
end

Darkmist is correct, it only works with CanCollide true parts. If you’re checking parts with either CanCollide == false, it will not be in the array.

Returns a table of all parts that are physically interacting with this part. If the part itself has CanCollide set to false, then this function will return an empty table UNLESS it has a TouchInterest (AKA: Something is connected to its Touched event). Parts that are adjacent but not intersecting are not considered touching.

If the Event TouchEnded isn’t reliable enough for you, I would recommend this.

Using a custom-made 3D Collision detection function (between two Parts), you can check if one part intersects another part.

This really nice article should help you get started.
https://wiki.roblox.com/index.php?title=User:EgoMoose/Articles/GJK_collision_detection

However, do note that it may be inefficient to loop such a function in this scenario.
You only need to check for collision after a change to either Part’s position is updated.

So you should utilise the Event Part:GetPropertyChangedSignal(“Position”) and run the collision either every time the position is updated or perhaps store the part’s position and only run collision when the same part’s position is at least some small distance away from it’s previous. I would connect this event when Touched is fired.

Lastly, when the collision function returns that the two part’s are no longer colliding, disconnect the relevant function which you connected to the Part:GetPropertyChangedSignal(“Position”) event as it is no longer needed until a future Touched event fires.

If this is for multiple parts, do the above for every possible pair of parts. (Possibly a more efficient way for multiple parts. Check out spatial partitioning and Collision detection optimization.)

For more efficiency, you can also add some simpler cases before defaulting to the less efficient, but accurate case. For e.g. check if one part’s centre is inside of the other Part -> If true then they collide, else, run the less efficient but full - collision detection.

Note: If you want to test that your parts are just touching, then you may want to pass off one of the Part’s Size as slightly larger. (Only by a small amount).

1 Like