Collision groups not behaving?

I’m trying to make players not collide with eachother when one is supposed to be invisible to others (in this instance they are in the character creator which is a physical location that they all take up together) but they are always colliding with each other no matter what, as if they are ignoring the CollisionGroupSetCollidable() functions completely

Script in ServerScriptService, print statements work:

local players = game:GetService("Players")

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local PhysicsService = game:GetService("PhysicsService")
PhysicsService:RegisterCollisionGroup("NoCollide")
PhysicsService:RegisterCollisionGroup("Player")

PhysicsService:CollisionGroupSetCollidable("NoCollide", "NoCollide", false)
PhysicsService:CollisionGroupSetCollidable("Player", "NoCollide", false)
PhysicsService:CollisionGroupSetCollidable("Player", "Default", true)

players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		repeat task.wait(0.1) until char:WaitForChild("Humanoid")

		for i, part in pairs(char:GetDescendants()) do
			if part:IsA("BasePart") then
				part.CollisionGroup = "NoCollide"
			end
		end
	end)
end)

ReplicatedStorage.ToggleCollision.OnServerEvent:Connect(function(player, x)
	local char = player.Character
	for i, part in pairs(char:GetDescendants()) do
		if part:IsA("BasePart") then
			if x then
				print("on")
				part.CollisionGroup = "Player"
			else
				print("off")
				part.CollisionGroup = "NoCollde"
			end
		end
	end
end)

LocalScript is just simple ReplicatedStorage.ToggleCollision:FireServer(true) (and false)

Are you testing this in studio? In some cases, the testing player may join the game before your script had a chance to load, and players.PlayerAdded will not fire, because the player’s already there. You could add print statements in the function if you need to test that.

If that’s the case, you could also add a “for _,v in pairs(game.Players:GetPlayers())” loop that applies the function to existing players, but you’d also have the problem of their character already being loaded, and CharacterAdded not firing the first time as a result.

This module by GFink may help simplify the issue, as it handles those edge cases automatically

I’m running it both in studio and on the actual ROBLOX client with 2 devices. Also to note that it doesn’t work even if both players have been clearly loaded in for quite some time (for some context, I am triggering the character creator using an NPC that takes about 20 seconds to walk to—the other player had already loaded in and is able to move around by that point)