Disabling Player Collisions

In Roblox, you may want players to pass through one another, for example in competitive games. To achieve this, two steps are necessary:

  1. Creating a collision group that controls what objects can collide
  2. A runtime script that assigns player characters to the collision group

Collision groups allow you to selectively enable and disable collisions between parts. By putting all player characters into the same collision group and disabling collisions within this group, we can ensure that players never collide with each other, while still colliding with the environment.

Creating the Collision Group

The first step is a setup routine that you run once directly in the Studio command bar. This script registers the collision group using PhysicsService:RegisterCollisionGroup(COLLISION_GROUP) and disables collisions between parts within this collision group using PhysicsService:CollisionGroupSetCollidable(COLLISION_GROUP, COLLISION_GROUP, false). Furthermore you can customise the name of the collision group by changing local COLLISION_GROUP = 'player' to any string you desire (Keep in mind that some values are reserved, e.g. “Default”).

--!strict

--[[
author: @quinacon
created: 2025/08/21
updated: 2025/08/31
]]

local COLLISION_GROUP = 'player'

local PhysicsService = game:GetService('PhysicsService')

local function initialise()
	if PhysicsService:IsCollisionGroupRegistered(COLLISION_GROUP) then
		error(`Collision group {COLLISION_GROUP} already exists. Please choose a different name.`)
	end

	if PhysicsService:GetMaxCollisionGroups() <= #PhysicsService:GetRegisteredCollisionGroups() then
		error(`Cannot create collision group {COLLISION_GROUP}: Maximum Number of collision groups reached.`)
	end
	
	local success, errorMessage = pcall(function()
		PhysicsService:RegisterCollisionGroup(COLLISION_GROUP)
		PhysicsService:CollisionGroupSetCollidable(COLLISION_GROUP, COLLISION_GROUP, false)
	end)
	
	if not success then
		error('Creating collision groups failed: ' .. errorMessage)
	end

	print(`Successfully created collision group {COLLISION_GROUP}`)
end

initialise()

The Runtime Script

To ensure that the script references the correct collision group, local COLLISION_GROUP = 'player' in this script has to match the value you chose during setup.
The addCharacter(character: Model) function sets the CollisionGroup property for both current parts and future parts to be added to the character.
The addPlayer(player: Player) function ensures that addCharacter() is applied each time a character of the player spawns.
Finally, the script connects addPlayer() to the PlayerAdded event event and iterates over all current players.

--!strict

--[[
author: @quinacon
created: 2025/08/21
updated: 2025/08/31
]]

local COLLISION_GROUP = 'player'

local Players = game:GetService('Players')

local function addCharacter(character: Model)
	character.DescendantAdded:Connect(function(basePart)
		if not basePart:IsA('BasePart') then
			return
		end
		
		basePart.CollisionGroup = COLLISION_GROUP
	end)
	
	for _, basePart in character:GetDescendants() do
		if not basePart:IsA('BasePart') then
			continue
		end
		
		basePart.CollisionGroup = COLLISION_GROUP
	end
end

local function addPlayer(player: Player)
	player.CharacterAdded:Connect(addCharacter)
	
	if player.Character then
		addCharacter(player.Character)
	end
end

Players.PlayerAdded:Connect(addPlayer)

for _, player in Players:GetPlayers() do
	task.spawn(addPlayer, player)
end
4 Likes