Ai pathfinding open door the wrong way

This is my first post, don’t mind my Language because i am asian :slight_smile:

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? fix code around 20 round but but i don’t know how to fix, somebody fix it?

  2. What is the issue? here the video

  3. What solutions have you tried so far? I tried to rewhrite but every is same

Here the code in npc model

script

local plrs = game:GetService("Players")
local runs = game:GetService("RunService")
local pfs = game:GetService("PathfindingService")
local ts = game:GetService("TweenService")
local collectSS = game:GetService("CollectionService")

local NPC = script.Parent
local Humanoid = NPC.Humanoids
local HumanoidRootPart = NPC:WaitForChild("HumanoidRootPart")
local BodyColor = NPC:WaitForChild("Body Colors")

repeat
	task.wait()
until workspace:FindFirstChild("Monster")
task.wait(1)
HumanoidRootPart:SetNetworkOwner(nil)

local OriginalSpeed = Humanoid.WalkSpeed

local openSound = script:WaitForChild("Open"):Clone()
local openKnobSound = script:WaitForChild("OpenKnob"):Clone()
local closeSound = script:WaitForChild("Close"):Clone()

openSound.Parent = HumanoidRootPart
openKnobSound.Parent = HumanoidRootPart
closeSound.Parent = HumanoidRootPart

local ColorTables = {
	[1] = {
		["Color"] = BrickColor.Red(),
	},
	[2] = {
		["Color"] = BrickColor.Green(),
	},
	[3] = {
		["Color"] = BrickColor.Blue(),
	}
}

local function betterWait(number)
	local delta = 0
	
	while delta < number do
		delta += runs.Heartbeat:Wait()
	end
	
	return delta
end

function Play_Sound(id, parent)
	local sound = Instance.new("Sound", parent)
	sound.SoundId = id
	sound.PlayOnRemove = true
	game:GetService("Debris"):AddItem(sound, sound.TimeLength)
end

local rnd = Random.new()
local pickColor = ColorTables[rnd:NextInteger(1, #ColorTables)]
BodyColor.TorsoColor = pickColor.Color

--NPC open door
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist
params.FilterDescendantsInstances = {HumanoidRootPart}
params.IgnoreWater = true

while betterWait(0.5) do
	local direction
	for _, model in pairs(collectSS:GetTagged("Door")) do
		direction = model.TriggeredPart.Position - HumanoidRootPart.Position
	end

	local raycast = workspace:Raycast(HumanoidRootPart.Position, direction, params)

	if raycast then
		local obj = raycast.Instance
		if obj then
			for _, model in pairs(collectSS:GetTagged("Door")) do
				local open = model.IsOpenned
				local db = false
				
				local hingeDoor = model:WaitForChild("Hinge")
				local Door = model:WaitForChild("Door")
				local Door_knob_In = model:WaitForChild("Door_knob_In")
				local Door_knob_Out = model:WaitForChild("Door_knob_Out")
				local TriggeredPart = model:WaitForChild("TriggeredPart")

				local currentCFrame = hingeDoor.CFrame
				
				local goal
				local tsInfo = TweenInfo.new(
					1,
					Enum.EasingStyle.Linear,
					Enum.EasingDirection.Out
				)

				if (raycast.Position - TriggeredPart.Position).Magnitude < 5 then
					if not db then
						db = true
						if not open.Value then
							open.Value = true
							Play_Sound("rbxassetid://8313170560", hingeDoor)
							Play_Sound("rbxassetid://5037969255", hingeDoor)
							goal = {CFrame = currentCFrame * CFrame.Angles(0, math.rad(90), 0)}
						else
							open.Value = false
							Play_Sound("rbxassetid://7038967181", hingeDoor)
							goal = {CFrame = currentCFrame * CFrame.Angles(0, math.rad(0), 0)}
						end

						local tween = ts:Create(hingeDoor, tsInfo, goal)
						tween:Play()
						tween.Completed:Wait()
						db = false
					end
				else
					--Bug >:(
				end
			end
		end
	end
end

Looks like your currentCFrame value is being updated upon each frame. So if your door is already rotated from the last open, it’ll turn another 90 degrees based on where the door’s CFrame is in that exact moment.
Before you run your while loop you need to pre-establish the CFrames of the doors. You can do this by caching them into a table. Then when you need the goal you already have your closed position and just need to offset 90 degrees for the open position (and negate the rotation based on which side they’re opening it from).

Also just a quick note here:

goal = {CFrame = currentCFrame * CFrame.Angles(0, math.rad(0), 0)}

^ This is the same as:

goal = {CFrame = currentCFrame}
1 Like

I did it and wrote it as you said and it’s the same.
:<

Is there an example of all the code lines?

Mind sending in the code that you changed it to? I’ve given you the answer but your application might be different. We can correct it from there.

local plrs = game:GetService("Players")
local runs = game:GetService("RunService")
local pfs = game:GetService("PathfindingService")
local ts = game:GetService("TweenService")
local collectSS = game:GetService("CollectionService")

local NPC = script.Parent
local Humanoid = NPC.Humanoids
local HumanoidRootPart = NPC:WaitForChild("HumanoidRootPart")
local BodyColor = NPC:WaitForChild("Body Colors")

repeat
	task.wait()
until workspace:FindFirstChild("Monster")
task.wait(1)
HumanoidRootPart:SetNetworkOwner(nil)

local OriginalSpeed = Humanoid.WalkSpeed

local openSound = script:WaitForChild("Open"):Clone()
local openKnobSound = script:WaitForChild("OpenKnob"):Clone()
local closeSound = script:WaitForChild("Close"):Clone()

openSound.Parent = HumanoidRootPart
openKnobSound.Parent = HumanoidRootPart
closeSound.Parent = HumanoidRootPart

local ColorTables = {
	[1] = {
		["Color"] = BrickColor.Red(),
	},
	[2] = {
		["Color"] = BrickColor.Green(),
	},
	[3] = {
		["Color"] = BrickColor.Blue(),
	}
}

local function betterWait(number)
	local delta = 0
	
	while delta < number do
		delta += runs.Heartbeat:Wait()
	end
	
	return delta
end

function Play_Sound(id, parent)
	local sound = Instance.new("Sound", parent)
	sound.SoundId = id
	sound.PlayOnRemove = true
	game:GetService("Debris"):AddItem(sound, sound.TimeLength)
end

local rnd = Random.new()
local pickColor = ColorTables[rnd:NextInteger(1, #ColorTables)]
BodyColor.TorsoColor = pickColor.Color

--NPC open door
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist
params.FilterDescendantsInstances = {HumanoidRootPart}
params.IgnoreWater = true

while betterWait(0.5) do
	local direction
	for _, model in pairs(collectSS:GetTagged("Door")) do
		direction = model.TriggeredPart.Position - HumanoidRootPart.Position
	end

	local raycast = workspace:Raycast(HumanoidRootPart.Position, direction, params)

	if raycast then
		local obj = raycast.Instance
		if obj then
			for _, model in pairs(collectSS:GetTagged("Door")) do
				local open = model.IsOpenned
				local db = false
				
				local hingeDoor = model:WaitForChild("Hinge")
				local Door = model:WaitForChild("Door")
				local Door_knob_In = model:WaitForChild("Door_knob_In")
				local Door_knob_Out = model:WaitForChild("Door_knob_Out")
				local TriggeredPart = model:WaitForChild("TriggeredPart")

				local currentCFrame = hingeDoor.CFrame
				
				local goal
				local tsInfo = TweenInfo.new(
					1,
					Enum.EasingStyle.Linear,
					Enum.EasingDirection.Out
				)

				if (raycast.Position - TriggeredPart.Position).Magnitude < 5 then
					if not db then
						db = true
						if not open.Value then
							open.Value = true
							Play_Sound("rbxassetid://8313170560", hingeDoor)
							Play_Sound("rbxassetid://5037969255", hingeDoor)
							goal = {CFrame = currentCFrame * CFrame.Angles(0, math.rad(90), 0)}
						else
							open.Value = false
							Play_Sound("rbxassetid://7038967181", hingeDoor)
							--goal = {CFrame = currentCFrame * CFrame.Angles(0, math.rad(0), 0)}
							goal = {CFrame = currentCFrame}
						end

						local tween = ts:Create(hingeDoor, tsInfo, goal)
						tween:Play()
						tween.Completed:Wait()
						db = false
					end
				else
					--Bug >:(
				end
			end
		end
	end
end

Looks like you missed this part in what I mentioned. This is the actual fix to your problem, not the code I posted.

Do This BEFORE your while loop:

  1. Make an empty table
  2. For every door, wait for your hinge to pop up and then do table[hingeDoor] = hingeDoor.CFrame

Do this IN your while loop:

  1. The goal’s CFrame will be:
  • table[hingeDoor] (for the door closing)
  • table[hingeDoor] * CFrame.Angles(0, math.rad(90), 0) (for the door opening)

Oh, thank you, IT WORK!!!
–My npc is stuck around corner of door, But forget it

1 Like

Um, friend?
I open all door in house, but My ai pathfinding open the wrog way again, Here this video :Sory for my video solution:

Do you have the script you are using with the above ‘solution’ ?

Thanks

script

local plrs = game:GetService("Players")
local runs = game:GetService("RunService")
local pfs = game:GetService("PathfindingService")
local ts = game:GetService("TweenService")
local collectSS = game:GetService("CollectionService")

local NPC = script.Parent
local Humanoid = NPC.Humanoids
local HumanoidRootPart = NPC:WaitForChild("HumanoidRootPart")
local BodyColor = NPC:WaitForChild("Body Colors")

repeat
	task.wait()
until workspace:FindFirstChild("Monster")

local OriginalSpeed = Humanoid.WalkSpeed

local openSound = script:WaitForChild("Open"):Clone()
local openKnobSound = script:WaitForChild("OpenKnob"):Clone()
local closeSound = script:WaitForChild("Close"):Clone()

openSound.Parent = HumanoidRootPart
openKnobSound.Parent = HumanoidRootPart
closeSound.Parent = HumanoidRootPart

local ColorTables = {
	[1] = {
		["Color"] = BrickColor.Red(),
	},
	[2] = {
		["Color"] = BrickColor.Green(),
	},
	[3] = {
		["Color"] = BrickColor.Blue(),
	}
}

local function betterWait(number)
	local delta = 0
	
	while delta < number do
		delta += runs.Heartbeat:Wait()
	end
	
	return delta
end

function Play_Sound(id, parent)
	local sound = Instance.new("Sound", parent)
	sound.SoundId = id
	sound.PlayOnRemove = true
	game:GetService("Debris"):AddItem(sound, sound.TimeLength)
end

local rnd = Random.new()
local pickColor = ColorTables[rnd:NextInteger(1, #ColorTables)]
BodyColor.TorsoColor = pickColor.Color

--NPC open door
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Blacklist
params.FilterDescendantsInstances = {HumanoidRootPart}
params.IgnoreWater = true

local DoorTable = {}
for _, model in pairs(collectSS:GetTagged("Door")) do
	local hingeDoor = model:WaitForChild("Hinge")
	DoorTable[hingeDoor] = hingeDoor.CFrame
end

while betterWait(0.5) do
	local direction
	for _, model in pairs(collectSS:GetTagged("Door")) do
		direction = model.TriggeredPart.Position - HumanoidRootPart.Position
	end

	local raycast = workspace:Raycast(HumanoidRootPart.Position, direction, params)

	if raycast then
		local obj = raycast.Instance
		if obj then
			for _, model in pairs(collectSS:GetTagged("Door")) do
				local open = model.IsOpenned
				local db = false
				
				local hingeDoor = model:WaitForChild("Hinge")
				local Door = model:WaitForChild("Door")
				local Door_knob_In = model:WaitForChild("Door_knob_In")
				local Door_knob_Out = model:WaitForChild("Door_knob_Out")
				local TriggeredPart = model:WaitForChild("TriggeredPart")

				local currentCFrame = hingeDoor.CFrame
				
				local goal
				local tsInfo = TweenInfo.new(
					1,
					Enum.EasingStyle.Linear,
					Enum.EasingDirection.Out
				)

				if (raycast.Position - TriggeredPart.Position).Magnitude < 5 then
					if not db then
						db = true
						Humanoid.WalkSpeed = 0
						if not open.Value then
							open.Value = true
							Play_Sound("rbxassetid://8313170560", hingeDoor)
							Play_Sound("rbxassetid://5037969255", hingeDoor)
							goal = {CFrame = DoorTable[hingeDoor] * CFrame.Angles(0, math.rad(90), 0)}
							Door.CanCollide = false
							Door_knob_In.CanCollide = false
							Door_knob_Out.CanCollide = false
						else
							open.Value = false
							Play_Sound("rbxassetid://7038967181", hingeDoor)
							goal = {CFrame = DoorTable[hingeDoor]}
							Door.CanCollide = true
							Door_knob_In.CanCollide = true
							Door_knob_Out.CanCollide = true
						end

						local tween = ts:Create(hingeDoor, tsInfo, goal)
						tween:Play()
						tween.Completed:Wait()
						Humanoid.WalkSpeed = OriginalSpeed
						db = false
					end
				else
					--Bug >:(
					Humanoid.WalkSpeed = OriginalSpeed
				end
			end
		end
	end
end