ROBLOX Pathfinding NPC is buggy

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

  1. What do you want to achieve? Keep it simple and clear!
    My NPC can’t catch up to the player no matter what + it lags/stutters a lot when near (goes back and forth slightly).
  2. What is the issue? Include screenshots / videos if possible!
    https://gyazo.com/9991df3f23873f4e5a2d2860fbc12fdb
    (Player was set to 10, NPC was set to 16)
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    script.Parent.HumanoidRootPart:SetNetworkOwner(nil)

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

--//Functions//--
local ServerStorage = game:GetService("ServerStorage")
local PlayerService = game:GetService("Players")
local SimplePath = require(ServerStorage.SimplePath)

--//Define NPC//--
local Dummy = script.Parent
local humrp = Dummy.HumanoidRootPart

--//Get Path//--
local Path = SimplePath.new(Dummy)

--//Chase Target//--
local function findTarget()
	local players = game.Players:GetPlayers()
	local MaxDistance = 9999999999
	local nearestTarget

	for i,v in pairs(players) do
		if (v.Character) then
			local target = v.Character
			local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude

			if (distance < MaxDistance) then
				nearestTarget = target
				MaxDistance = distance
			end
		end
	end

	return nearestTarget
end

while task.wait() do
	local target = findTarget(script.Parent.HumanoidRootPart)

	if target ~= nil then
		Path:Run(target.Torso.Position, target)
	end

	Dummy.Humanoid.Died:Connect(function()
		script:Destroy()
	end)
end

--- I'm using SimplePath Module

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

2 Likes

Check through this post.

1 Like

Thank you. I indeed need this code. I have been struggling with AI pathfinding for so long.

local npc = --[[ Reference to your NPC here --]]
local target = --[[ Reference to your target position here --]]

local pathfindingService = game:GetService("PathfindingService")

-- Function to set a new target for the NPC
local function setNewTarget(newTarget)
    target = newTarget
end

-- Function to handle pathfinding
local function navigateToTarget()
    local path = pathfindingService:CreatePath({
        AgentRadius = 2, -- Adjust as needed
        AgentHeight = 5, -- Adjust as needed
        AgentCanJump = true,
        AgentJumpHeight = 10, -- Adjust as needed
        })
    
    path:ComputeAsync(npc.Position, target)
    path:MoveTo(npc)

    path.Changed:Connect(function(status)
        if status == Enum.PathStatus.Complete then
            print("Destination reached!")
            -- Optional: set a new target here if needed
        elseif status == Enum.PathStatus.Cancelled then
            print("Pathfinding cancelled")
        end
    end)
end

-- Connect the navigate function to a button click or some other event
-- Example: npc.ClickDetector.MouseClick:Connect(navigateToTarget)

-- Optional: Connect a function to update the target dynamically
-- Example: npc.Touched:Connect(function(otherPart)
--            if otherPart:IsA("Part") and otherPart.Parent:IsA("Model") then
--                setNewTarget(otherPart.Position)
--            end
--          end)

Make sure to replace the placeholder comments with your actual NPC reference and target position. This script includes optional features like updating the target dynamically upon touch and printing messages for better debugging. Adjust the parameters in the pathfindingService:CreatePath function based on your NPC’s characteristics.

Remember to connect the navigateToTarget function to an event that triggers the pathfinding, like a button click or any other interaction with your NPC.

My code if I did anything wrong

local npc = script.Parent.HumanoidRootPart
	local target = workspace.part

	local pathfindingService = game:GetService("PathfindingService")

-- Function to set a new target for the NPC
local function setNewTarget(newTarget)
	target = newTarget
end

-- Function to handle pathfinding
local function navigateToTarget()
	local path = pathfindingService:CreatePath({
		AgentRadius = 2, -- Adjust as needed
		AgentHeight = 5, -- Adjust as needed
		AgentCanJump = true,
		AgentJumpHeight = 10, -- Adjust as needed
	})

	path:ComputeAsync(npc.Position, target)
	path:MoveTo(npc)

	path.Changed:Connect(function(status)
		if status == Enum.PathStatus.Complete then
			print("Destination reached!")
			-- Optional: set a new target here if needed
		elseif status == Enum.PathStatus.Cancelled then
			print("Pathfinding cancelled")
		end
	end)
end

npc.Parent.Torso.ProximityPrompt.Triggered:Connect(navigateToTarget)

-- Connect the navigate function to a button click or some other event
-- Example: npc.ClickDetector.MouseClick:Connect(navigateToTarget)

-- Optional: Connect a function to update the target dynamically
-- Example: npc.Touched:Connect(function(otherPart)
--            if otherPart:IsA("Part") and otherPart.Parent:IsA("Model") then
--                setNewTarget(otherPart.Position)
--            end
--          end)

That myabe error think hmmm let see me

Don’t even use task.wait() simple path already has a built in wait, but you should add a task.wait() if there is no target to prevent crashing.

-- Get the instance (replace "YourInstanceName" with the actual name of your instance)
local yourInstance = workspace:WaitForChild("YourInstanceName")

-- Check if the instance exists
if yourInstance then
    -- Get the position of the instance
    local instancePosition = yourInstance.Position
    
    -- Print the position (optional)
    print("Instance Position:", instancePosition)

    -- Convert the position to a Vector3
    local instanceVector3 = Vector3.new(instancePosition.X, instancePosition.Y, instancePosition.Z)

    -- Now you can use instanceVector3 as a Vector3
    print("Converted Vector3:", instanceVector3)
else
    warn("Instance not found.")
end

Sure, if you’re having trouble converting a Instance to a Vector3 in Roblox, it might be due to a mismatch in data types. Here’s a simple script that shows how to retrieve the position of an instance and convert it to a Vector3:

-- Get the instance (replace "YourInstanceName" with the actual name of your instance)
local yourInstance = workspace:WaitForChild("YourInstanceName")

-- Check if the instance exists
if yourInstance then
    -- Get the position of the instance
    local instancePosition = yourInstance.Position
    
    -- Print the position (optional)
    print("Instance Position:", instancePosition)

    -- Convert the position to a Vector3
    local instanceVector3 = Vector3.new(instancePosition.X, instancePosition.Y, instancePosition.Z)

    -- Now you can use instanceVector3 as a Vector3
    print("Converted Vector3:", instanceVector3)
else
    warn("Instance not found.")
end

Make sure to replace “YourInstanceName” with the actual name of your instance. This script first checks if the instance exists, gets its position, converts the position to a Vector3, and then you can use the instanceVector3 variable as needed in your code.

Add the position of the target.?

path:ComputeAsync(npc.Position, target.Position)

still says I can’t cast Instance to vector3, did I code it in right?

local npc = script.Parent.HumanoidRootPart
local target = workspace.Part

local pathfindingService = game:GetService("PathfindingService")

-- Function to set a new target for the NPC
local function setNewTarget(newTarget)
	target = newTarget
end

-- Function to handle pathfinding
local function navigateToTarget()
	local path = pathfindingService:CreatePath({
		AgentRadius = 2, -- Adjust as needed
		AgentHeight = 5, -- Adjust as needed
		AgentCanJump = true,
		AgentJumpHeight = 10, -- Adjust as needed
	})
	
	-- Check if the instance exists
	if npc then
		-- Get the position of the instance
		local instancePosition = npc.Position

		-- Print the position (optional)
		print("Instance Position:", instancePosition)

		-- Convert the position to a Vector3
		local instanceVector3 = Vector3.new(instancePosition.X, instancePosition.Y, instancePosition.Z)

		-- Now you can use instanceVector3 as a Vector3
		print("Converted Vector3:", instanceVector3)
		
		path:ComputeAsync(instanceVector3, target)
		path:MoveTo(npc)
	else
		warn("Instance not found.")
	end

	path.Changed:Connect(function(status)
		if status == Enum.PathStatus.Complete then
			print("Destination reached!")
			-- Optional: set a new target here if needed
		elseif status == Enum.PathStatus.Cancelled then
			print("Pathfinding cancelled")
		end
	end)
end

npc.Parent.Torso.ProximityPrompt.Triggered:Connect(navigateToTarget)

-- Connect the navigate function to a button click or some other event
-- Example: npc.ClickDetector.MouseClick:Connect(navigateToTarget)

-- Optional: Connect a function to update the target dynamically
-- Example: npc.Touched:Connect(function(otherPart)
--            if otherPart:IsA("Part") and otherPart.Parent:IsA("Model") then
--                setNewTarget(otherPart.Position)
--            end
--          end)