How to make the NPC ignore the door?

I wonder how to make the npc move anyway without hot the wall but ignore the door.I am new at scripting and still learning.

My AI script:

    local npc = script.Parent
    local humanoid = npc.Humanoid
    npc.PrimaryPart:SetNetworkOwner(nil)
    local camera = workspace.CurrentCamera
    local cam = npc.Head.Cam
    local killed = false

    local tweenService = game:GetService("TweenService")
    local changeCam = tweenService:Create(camera, TweenInfo.new(1), {CFrame = cam.CFrame})

    local function canSeeTarget(target)
    	local origin = npc.HumanoidRootPart.Position
    	local direction = (target.HumanoidRootPart.Position - npc.HumanoidRootPart.Position).unit * 80
    	local ray = Ray.new(origin, direction)
    	
    	local hit, pos = workspace:FindPartOnRay(ray, npc)
    	
    	
    	if hit then
    		if hit:IsDescendantOf(target) then
    			return true
    		end
    	else
    		return false
    	end
    end

    local function findTarget()
    	local players = game.Players:GetPlayers()
    	local maxDistance = 80
    	local nearestTarget
    	
    	for index, player in pairs(players) do
    		if player.Character then
    			local target = player.Character
    			local distance = (npc.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
    			
    			if distance < maxDistance and canSeeTarget(target) then
    				nearestTarget = target
    				maxDistance = distance
    			end
    		end
    	end
    	
    	return nearestTarget
    end

    local function getPath(destination)
    	local PathfindingService = game:GetService("PathfindingService")
    	
    	local pathParams = {
    		["AgentHeight"] = 15,
    		["AgentRadius"] = 4,
    		["AgentCanJump"] = false
    	}
    	
    	local path = PathfindingService:CreatePath(pathParams)
    	
    	path:ComputeAsync(npc.HumanoidRootPart.Position, destination.Position)
    	
    	return path
    end

    local function attack(target)
    	local distance = (npc.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude

    	if distance > 0 then
    		humanoid:MoveTo(target.HumanoidRootPart.Position)
    	end
    	
    	npc.HumanoidRootPart.Touched:Connect(function()
    		camera.CameraType = Enum.CameraType.Scriptable
    		camera.CameraSubject = cam
    		if killed == false then
    			killed = true
    			local attackAnim = humanoid:LoadAnimation(script.Attack)
    			target.HumanoidRootPart.Anchored = true
    			npc.HumanoidRootPart.Anchored = true
    			changeCam:Play()
    			attackAnim:Play()
    			attackAnim.Stopped:Wait()
    			target.Humanoid.Health = 0
    			target.HumanoidRootPart.Anchored = false
    			npc.HumanoidRootPart.Anchored = false
    			wait(0.2)
    			killed = false
    		end
    	end)
    end

    local function walkTo(destination)
    	
    	local path = getPath(destination)
    	
    	if path.Status == Enum.PathStatus.Success then
    		for index, waypoint in pairs(path:GetWaypoints()) do
    			local target = findTarget()
    			if target and target.Humanoid.Health > 0 then
    				attack(target)
    				break
    			else
    				humanoid:MoveTo(waypoint.Position)
    				humanoid.MoveToFinished:Wait()
    			end
    		end
    	else
    		humanoid:MoveTo(destination.Position - (npc.HumanoidRootPart.CFrame.LookVector * 10))
    	end
    end

    function patrol()
    	local waypoints = workspace.waypoints:GetChildren()
    	local randomNum = math.random(1, #waypoints)
    	walkTo(waypoints[randomNum])
    end

    while wait(0.25) do
    	patrol()
    end

The Door script:

local door = script.Parent
local frame = door.frame
local open = door.open
local close = door.close
local main = script.main
local click = frame.click

local opened = false

local tweenService = game:GetService("TweenService")
local bounce = TweenInfo.new(0.6,Enum.EasingStyle.Bounce,Enum.EasingDirection.Out,0,false,0)

function doorSystem()
	if opened == false then
		local opening = tweenService:Create(frame, bounce, {CFrame = open.CFrame})
		main:Play()
		opening:Play()
		opened = true
	else
		local closing = tweenService:Create(frame, bounce, {CFrame = close.CFrame})
		main:Play()
		closing:Play()
		opened = false
	end
end

click.MouseClick:Connect(doorSystem)

I really need to fix this ASAP.Hope you can help me.

Sorry if my english is suck

Edit:The door model is located in Door folder and it have many of them

What do you mean by this? Do you mean you want the npc to be able to go through the door?

1 Like

Yes,I want to make it but I don’t know how to do it.

Maybe doing another function and variable for the door, and if he see it change the target to the door.

This way he go to the door, then change the path to after the door.

1 Like

Maybe add all the parts of the NPC to a colission group, and allow it to go through the door?

1 Like

No, I want to make the NPC ignore the door + open the door after touch the door frame

Just check if the name of the object touching is part of the NPC by doing script.Parent

1 Like

Pathfinding service does not take Collision Filtering | Roblox Creator Documentation using PhysicsService | Roblox Creator Documentation into account when creating the path. However, in the engine feature request I saw a post that was answered by the Roblox staff about this that said they were planning on updating it to change this. That, however, is outside the scope of this question.

If you already have the pathfinding set up, then every time you opened or closed the door you should re-calculate the path.
For example:

function doorSystem()
	if opened == false then
		local opening = tweenService:Create(frame, bounce, {CFrame = open.CFrame})
		main:Play()
		opening:Play() -- You should wait for this to complete
		opening.Completed:Wait() -- Now we waited for it to complete
		opened = true
	else
		local closing = tweenService:Create(frame, bounce, {CFrame = close.CFrame})
		main:Play()
		closing:Play()
		closing.Completed:Wait() -- Same thing here
		opened = false
	end

	-- Your code or function call to re-calculate the npc path
end

Also, if are already storing the variables to create the tween and they don’t change, then you should not have

local opening = tweenService:Create(frame, bounce, {CFrame = open.CFrame})
local closing = tweenService:Create(frame, bounce, {CFrame = close.CFrame})

declared in the function, as it’s creating a new tween every time. This will reduce performance when you can instead define them like this:

local door = script.Parent
local frame = door.frame
local open = door.open
local close = door.close
local main = script.main
local click = frame.click

local opened = false

local tweenService = game:GetService("TweenService")
local bounce = TweenInfo.new(0.6,Enum.EasingStyle.Bounce,Enum.EasingDirection.Out,0,false,0)

-- Now we only define them once
local opening = tweenService:Create(frame, bounce, {CFrame = open.CFrame})
local closing = tweenService:Create(frame, bounce, {CFrame = close.CFrame})

function doorSystem()
	if opened == false then
		main:Play()
		opening:Play()
		opening.Completed:Wait()
		opened = true
	else
		main:Play()
		closing:Play()
		closing.Completed:Wait()
		opened = false
	end
end

click.MouseClick:Connect(doorSystem)


EDIT:
I realized that the npc and door use two different script. In this case you’ll need to use a BindableEvent | Roblox Creator Documentation to communicate between these two scripts. Usually you create BindableEvent and place it in ServerStorage | Roblox Creator Documentation. So in your scripts you want to add a variable that stores the bindable event. So you would do something like:

local DoorEvent = game:GetService("ServerStorage"):WaitForChild("BindableEvent") -- You can rename the bindable event to "DoorEvent" or something else you want to use

Then in the door script you would the BindableEvent | Roblox Creator Documentation to communicate to the other script that the path needs to be re-calculated:

function doorSystem()
	if opened == false then
		main:Play()
		opening:Play()
		opening.Completed:Wait()
		opened = true
	else
		main:Play()
		closing:Play()
		closing.Completed:Wait()
		opened = false
	end

	DoorEvent:Fire() -- Fires the event letting to let us know to recalculate the path
end

In the npc script you can use the BindableEvent | Roblox Creator Documentation to connect to the function that creates your waypoints.

DoorEvent.Event:Connect(WaypointCreatorFunction) -- IDK how you create your waypoints.

However, if you already have waypoints on each side of the door and the door is closed then you simple connect it to the calculate path function instead:

Also, the wait here is WAY to short. You want to give your npc time to get to the waypoint.

2 Likes

Alright, re-looking at your code, I think you just need to edit the npc script. You don’t need to use BindableEvent’s or anything. I recommend that you look at the Character Pathfinding | Roblox Creator Documentation article. It is very helpful and also accounts for blocked paths.