How to make an NPC only Part

I am trying to make an obby where you must finish before the walking NPC touches you. I have attached a kill brick at the front of the NPC to kill the players on touch.

Some of the jumps in the obby don’t let the NPC walk over it and it just falls off the map. Is there an efficient way to do this? I’ve tried making a bridge that covers the whole obby with a LocalScript inside it to check if the thing touching it is an NPC and then to turn CanCollide on only for the NPC and not the players but it does not seem to work.

I even added a Print command att the very start to verify that the script it working but it’s not, even though the LocalScipt is inside of Workspace.

In simpler terms, I am trying to make a part that can only be walked on by the NPC not the players.

Below is the picture of the obby with the red bit being the bridge for the NPC, it will be transparent .

I’ve heard of using something like CollisionGroups but I’m not sure if that will be the best option in this case.

This is the code inside the LocalScript inside the bridge part.

--Variables--
local Brick = script.Parent
local Workspace = game.Workspace
--End--

--Code--
Brick.Touched:Connect(function(hit)
	
	local player = hit.Parent:GetPlayerFromCharacter()

	
	if player.Name == "Noob" then
		Brick.CanCollide = false
	end
end)

Is there an alternative way of doing this and why is the script not working?
Many thanks.

6 Likes

You could add a BoolValue and name it isNpc then check for if it exists inside the object probably not the best way though. Here’s an example:

Brick.Touched:Connect(function(hit)

	local player = hit.Parent:GetPlayerFromCharacter(hit.Parent)
	if player:FindFirstChild("isNpc") then
		Brick.CanCollide = false
	end
end)

Use this in a server sided script and not a local script.

4 Likes

LocalScripts can’t run in workspace, you need to put it somewhere else

This is definitely the best option, you can do something like this:

--script in ServerScriptService
local bricks = {game.Workspace.Brick} -- insert all of the bricks that can only be walked through by the NPC
local NPC = workspace.NPC -- change to NPC's location

local PhysicsService = game:GetService("PhysicsService")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:RegisterCollisionGroup("NPCParts")
PhysicsService:CollisionGroupSetCollidable("Characters", "NPCParts", false) -- set characters not collidible with NPCParts

local function SetCollisionGroup(char) -- sets character's collision group
for i,v in pairs(char:GetDescendants()) do
if v:IsA("BasePart") then 
v.CollisionGroup = "Characters"
end
end
end

game.Players.PlayerAdded:Connect(function(plr) 
if player.Character then SetCollisionGroup(player.Character) end
player.CharacterAdded:Connect(SetCollisionGroup)
end)

for i,v in pairs(NPC:GetDescendants()) do -- set npc's collision groups
if v:IsA("BasePart") then
v.CollisionGroup = "NPCParts"
end
end

for i,v in pairs(bricks) do -- set bricks collision groups
v.CollisionGroup = "NPCParts"
end

Now the NPC can walk over the bricks and the players can’t, however the NPC will not collide with players
Don’t set the bricks’ CanCollide to false by the way.

4 Likes

Thanks so much for the quick reply and a detailed response, it worked. Thanks for putting comments in the script it made it easy to edit and follow.

1 Like

How would I make parts the is CanCollide off for the NPC but is CanCollide on for the players, basically the reverse?

All you need to do is change this line to v.CollisionGroup = "Characters"

It does not work. This is the script:

local wps = game.Workspace
![NPCstuck|690x417](upload://7CSczH3ZEDQ8kDRObiJG7Nxxo36.jpeg)
local bricks = {

	wps.Ladder, 
	} -- insert all of the bricks that can only be walked through by the NPC
local NPC = workspace.Noob -- change to NPC's location

local PhysicsService = game:GetService("PhysicsService")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:RegisterCollisionGroup("NPCParts")
PhysicsService:CollisionGroupSetCollidable("Characters", "NPCParts", false) -- set characters not collidible with NPCParts

local function SetCollisionGroup(char) -- sets character's collision group
	for i,v in pairs(char:GetDescendants()) do
		if v:IsA("BasePart") then 
			v.CollisionGroup = "Characters"
		end
	end
end

game.Players.PlayerAdded:Connect(function(plr) 
	if plr.Character then SetCollisionGroup(plr.Character) end
	plr.CharacterAdded:Connect(SetCollisionGroup)
end)

for i,v in pairs(NPC:GetDescendants()) do -- set npc's collision groups
	if v:IsA("BasePart") then
		v.CollisionGroup = "Characters"
	end
end

for i,v in pairs(bricks) do -- set bricks collision groups
	v.CollisionGroup = "Characters"
end```

He just walks right into the part, and I have checked it is the only part in workspace called Ladder.

Only change the ladder’s collision groups to Characters, don’t change the NPC’s

1 Like

2 Things.

#1 Instead of falling right through the part for the player it juts makes me float, I think it the humanoidRootPart that’s not letting it fall through.

#2 The NPC just stops here in the running animation, and I’m not sure why.


Maybe the parts just get added after the charAdded runs? You can do this

local wps = game.Workspace
local bricks = {

	wps.Ladder, 
} -- insert all of the bricks that can only be walked through by the NPC
local NPC = workspace.Noob -- change to NPC's location

local PhysicsService = game:GetService("PhysicsService")
PhysicsService:RegisterCollisionGroup("Characters")
PhysicsService:RegisterCollisionGroup("NPCParts")
PhysicsService:CollisionGroupSetCollidable("Characters", "NPCParts", false) -- set characters not collidible with NPCParts

local function DescendantAdded(descendant) -- descendant added
	if descendant:IsA("BasePart") then 
		descendant.CollisionGroup = "Characters"
	end
end

local function SetCollisionGroup(char) -- sets character's collision group
	for i,v in pairs(char:GetDescendants()) do
		DescendantAdded(v)
	end
end

game.Players.PlayerAdded:Connect(function(plr) 
	if plr.Character then SetCollisionGroup(plr.Character) end
	local DescAdded
	plr.CharacterAdded:Connect(function(char)
		SetCollisionGroup(char)
		DescAdded = char.DescendantAdded:Connect(DescendantAdded) -- connects descendant added
		
		plr.CharacterAdded:Once(function() -- disconnects event when player respawns to prevent leaks
			DescAdded:Disconnect()
			return
		end)
	end)
end)

for i,v in pairs(NPC:GetDescendants()) do -- set npc's collision groups
	if v:IsA("BasePart") then
		v.CollisionGroup = "NPCParts"
	end
end

for i,v in pairs(bricks) do -- set bricks collision groups
	v.CollisionGroup = "Characters"
end

I don’t think this is relevant to the problem, can you tell me how it’s related?

Also is the NPC cloned somewhere else or it already exists in workspace?

The NPC already exists in workspace. It’s related because even though cancollide is on on the bridge part, the NPC just stops and does not seem to want to walk on it. I use the Humanoid:MoveTo command to go to an invisible part at the end but the NPC just stops, and this Script is also located in ServerScriptService. Anyway thanks for the edited script ill try it soon.

Here is the code for moving the NPC if it helps:

local points = game.Workspace.Point--points is a folder in workspace

function noobWalk ()
	noob.HumanoidRootPart.Anchored = false
	noob.Humanoid:MoveTo(points.Finish.Position)
	noob.Humanoid.MoveToFinished:Wait()
end

wait (8)
noobWalk()
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.