Detecting Collisions

Collision events occur when BaseParts intersect or un-intersect in the 3D world. These events can be detected through the Touched and TouchEnded events respectively.

When considering collision handling on parts, note the following:

  • A part's CanCollide property affects whether it will physically collide with other parts and cause forces to act upon them.
  • Even if CanCollide is disabled for a part, you can detect intersection and un-intersection through collision events.
  • A part's CanTouch property determines whether it triggers collision events. If set to false, neither Touched nor TouchEnded will fire.

Touched Event

The Touched event fires when a part comes in contact with another part. It only fires as a result of physical simulation and will not fire when the part's Position or CFrame is explicitly set such that it overlaps another part.

The following code pattern shows how the Touched event can be connected to a custom onTouched function. Note that the event sends the otherPart argument to the function, indicating the other part involved in the collision.

Part Collision

local part = workspace.Part
local function onTouched(otherPart)
print(part.Name .. " collided with " .. otherPart.Name)
end
part.Touched:Connect(onTouched)

TouchEnded Event

The TouchEnded event fires when the entirety of a part exits the collision bounds of another part. It only fires as a result of physical simulation and will not fire when the part's Position or CFrame is explicitly set such that it stops overlapping another part.

Non-Collision Detection

local part = workspace.Part
local function onTouchEnded(otherPart)
print(part.Name .. " is no longer touching " .. otherPart.Name)
end
part.TouchEnded:Connect(onTouchEnded)

Model Collisions

Models such as player characters contain multiple parts. Since a model as a whole cannot be connected to the Touched or TouchEnded events, you'll need to loop through its children and connect the custom onTouched function to each child BasePart.

Model Collision

local model = workspace.Model
local function onTouched(otherPart)
-- Ignore instances of the model coming in contact with itself
if otherPart:IsDescendantOf(model) then return end
print(model.Name .. " collided with " .. otherPart.Name)
end
for _, child in pairs(model:GetChildren()) do
if child:IsA("BasePart") then
child.Touched:Connect(onTouched)
end
end

Collision Fidelity

The CollisionFidelity property, accessible only for MeshParts and UnionOperations, determines how closely the physical hitbox matches its visual representation.

In most cases, the Default setting is suitable, but other settings can be selected based on best performance (Hull or Box) versus accuracy (PreciseConvexDecomposition).

Original mesh
Box
Hull
Default
PreciseConvexDecomposition