My NPC can go through a local part? It's weird

Hello I’m DarkBegin and I have a problem with my local script in StarterPlayerScripts.
I made this script to avoid some NPCs attack players in the spawn lobby. So I made a local script to destroy walls named “MonMur” for players. NPC monsters are not supposed to ignore the walls but they do.


Here my green wall, and the local script called “PasserAilleurs” :

if not game:IsLoaded() then
	game.Loaded:Wait()
end
for _, part in ipairs(workspace:GetChildren()) do
	if part.Name == "MonMur" then
		part:Destroy()
	end
	end

Any idea why the NPCs with a humanoid called Zombie can ignore these walls??
Am I clear?
Actually the script works half (it only destroy walls, but for everyone…)

Kind of confuse on what you’re saying. So you have a Zombie NPC that you DON’T want to enter spawn. You’ve created collidable walls on the server and disable the collision on the client so players can pass through.

However NPCs are still targeting players within the spawn? Are the NPCs walking through the actual walls? Or are they just mindlessly trying to get the player in the spawn but are still being blocked by the wall? How are you detecting players, etc?

To answer your first paragraph, yes.

NPCs are still targeting the players everywhere even if they can’t reach them.
I used pathfinding and a script to follow from distance, but I don’t think that’s the problem.

I’m a bit confused about what you mean, you said the zombies can go through a local part but then say you deleted the part for all the players, and you only want the zombies to get stopped at the barrier?

Are you sure the walls are created and collidable on the server? Disable the script that destroys the wall for players and see if the NPC OR players still can walk through.

It doesn’t matter if there are zombies in fact. Only the players can’t see this wall anymore.

yes trust me, they have collision at the beginning

1 Like

Did you set the part to collide on the server?

I have experienced this exact issue. Strangely, locally setting a part’s collision off or something similar replicates to server-sided objects somewhat as if the game was in Experimental Mode.
Here is a video of a local script setting the baseplate’s collision to false, while my character is anchored:

robloxapp-20211124-2244599.wmv (1.2 MB)

I don’t know why this happens, possibly a server Network Ownership problem considering it targets closer objects as displayed in the video. However, the solution to this problem is by using a server script to set the collision groups of players and the walls:

local PhysicsService = game:GetService("PhysicsService")

PhysicsService:CreateCollisionGroup("Player")
PhysicsService:CreateCollisionGroup("Wall")

for _, Wall in pairs(workspace:GetChildren()) do
	if Wall.Name == "MonMur" then
		PhysicsService:SetPartCollisionGroup(Wall,"Wall")
	end
end

PhysicsService:CollisionGroupSetCollidable("Player","Wall",false)

game:GetService("Players").PlayerAdded:Connect(function(Player)
	local CurrentConnection
	Player.CharacterAdded:Connect(function(Char)
		if CurrentConnection then
			CurrentConnection:Disconnect()
		end
		for _, Part in pairs(Char:GetChildren()) do
			if Part:IsA("BasePart") then
				PhysicsService:SetPartCollisionGroup(Part,"Player")
			end
		end
		CurrentConnection = Char.DescendantAdded:Connect(function(Part)
			if Part:IsA("BasePart") then
				PhysicsService:SetPartCollisionGroup(Part,"Player")
			end
		end)
	end)
end)

The walls MUST have CanCollide set to true in order for collision groups to function. Otherwise, collision groups are ignored.

Why not just assign the NPCs to the "Player" collision group, and use PhysicsService:CollisionGroupSetCollidable("Player","Wall",true)?

Other than the fact that parts ignore collision groups when CanCollide is false, from the research I have done, it seems as though Roblox made CollisionGroupSetCollidable() to check the booleans like this: If true, treat it as default collisions do. If false, the parts within both groups don’t collide with each other. So basically, using true is useless in this method. In my opinion, very poor and inconvenient design.

I also noticed you have cars that you may need to drive out of the barrier. To allow other parts to pass through you should either add some sort of value to each part you wish to pass through the barrier (such as an Attribute), or add those parts to a table. In this case I just used Attributes, but it’s easy to write the code in either way. So you can add the code below to the previous code for setting player collisions.

for _, Part in pairs(workspace:GetDescendants()) do
	if Part:IsA("BasePart") and Part:GetAttribute("WallCollideOff") then
		PhysicsService:SetPartCollisionGroup(Part,"Player")
	end
end

workspace.DescendantAdded:Connect(function(Part)
	if Part:IsA("BasePart") and Part:GetAttribute("WallCollideOff") then
		PhysicsService:SetPartCollisionGroup(Part,"Player")
	end
end)

Unfortunately with Collision Groups, Roblox has kind of forced this to be a long process of elimination to leave the NPCs out in this case. But at least it’s functional.

1 Like

Use collision groups to achieve this kind of behavior.

Thank you a lot for your good explanations!
To be honest I’m not very good to understand how to script and make variable stuff.
But thanks to you, I understood everything!!
I added attribute as you said, obviously, I found it was a boolean :grinning_face_with_smiling_eyes:
UPDATE : If the npc gets on the car and we go back to the spawn, the npc goes with us 0_o