NoobPath | Easy Pathfinding

I got this error

ReplicatedStorage.NoobPath:172: attempt to index nil with 'Connect'

it says that the error is coming from NoobPath:Activate()

function NoobPath:Activate()
	if Server then
		self.DescendantAddedC = self.Character.DescendantAdded:Connect(function(Item)
			if Item:IsA("BasePart") and Item:CanSetNetworkOwnership() then
				Item:SetNetworkOwner(nil)
			end
		end)
	end
	
     -- ERROR AT THE LINE BELOW
	 self.MoveFinishedC = self.MoveFinished:Connect(function(Success) -- if you are using custom MoveFinished, Fire(true) if successfully reached
		if self.Idle then
			return
		end
		if Success then
			local NextWaypoint = self:GetNextWaypoint()
			if NextWaypoint then
				self:TravelNextWaypoint()
				self.WaypointReached:Fire(self:GetWaypoint(), NextWaypoint)

			else
				self:Arrive()
			end
		else
			self:Stop()
			self.Trapped:Fire("ReachFailed")
		end
	end)
	self.JumpFinishedC = self.JumpFinished:Connect(function()
		self.InAir = false
	end)
end

It seems like you are using constructor .new() without MoveFinished signal given, which is why it caused an error. If you are using Humanoid, try .Humanoid() constructor.

Custom Movement Example (AlignPosition)

local GS = require(workspace.NoobPath.GoodSignal)
local JumpS = GS.new()
local MoveS = GS.new()

local JumpC = JumpS:Connect(function()
	print("JumpFinished")
end)
local MoveC = MoveS:Connect(function()
	print("MoveFinished")
end)

local PrimaryPart = script.Parent.PrimaryPart

local AlignPos = Instance.new("AlignPosition")
AlignPos.Parent = PrimaryPart
local Attachment = Instance.new("Attachment")
Attachment.Parent = PrimaryPart
AlignPos.Attachment0 = Attachment
AlignPos.Mode = Enum.PositionAlignmentMode.OneAttachment
AlignPos.MaxForce = 25000
AlignPos.Responsiveness = 50

local Guy
Guy = require(workspace.NoobPath).new(
	script.Parent,
	{}, -- AgentParams
	function(Pos)
		print("Moved")
		AlignPos.Position = Pos - PrimaryPart.PivotOffset.Position
		
		local Break = false
		local C
		C = Guy.Overide:Connect(function()
			C:Disconnect()
			Break = true
		end)
		
		task.defer(function()
			while not Break and (PrimaryPart:GetPivot().Position - Pos).Magnitude > 2 do
				task.wait()
			end
			if not Break then
				MoveS:Fire(true)
			end
		end)
	end,
	function()
		-- Custom jumping is complex, I won't implement it in this example
		JumpS:Fire()
	end,
	JumpS,
	MoveS
)
Guy.Visualize = true

Guy:Run(workspace.SpawnLocation)

while task.wait(0.1) do
	Guy:Run()
end 

2 Likes

Does this mean we should not turn on the new feature, or is the new feature compatible with Noobpath?

Also anyway of having an open source testing place?

Thanks

the new features are compatible, what I mentioned are features NoobPath offer/improvements to SimplePath

Ok, thanks,

what about a testing place, where the npc have different capabilities… like some are fast and smart, some are slow and smart , some are fast and not so smart…

can different NPCs have different things like above?

NoobPath is just Pathfinding service but simplified and improved. What you mentioned are specific behaviors that will require custom logic and has to be implemented by you.

mm ok… seems like it would be cool to have in noobpath…

is there any kind of global debugging that can be turned off and on… like to see what it is doing when testing things out, but being able to toggle it off at other times?

you can turn visualize on, and add connection to the error, jumpfinished, movefinished, overide, trapped, reached, waypoint reached… events to detect what is happening

Do you know any way to make my npc stop spamming jump?, When i get close to him, he stops, but when i am far away, he starts spamming jump, i noticed this doesn’t happens when i delete the function on “onTrapped” that where it’s telling him to jump, but if i delete it , i won’t have a way to make him jump thru obstacles,and also it kinda takes long to jump, which is what i don’t want , otherwise it’s actually kinda better than SimplePath, these are the only bugs i’ve found

my current code goes like this :

local pathfindPosition = Vector3.new()

local path = Pathfinding.Humanoid(rake, 
	{
		AgentHeight = 4, -- 3
		AgentRadius = 2, -- 2
		AgentCanJump = true,
		AgentCanClimb = true,
		Costs = {
			PathfindAvoid = 9999,
			Truss = 1,
		},
		PathSettings = {
			SupportPartialPath = true,
		},
		WaypointSpacing = 5.5 -- 10
	}
)

path.Reached:Connect(function(Waypoint, IsPartial)
	task.wait(.1)
	path:Run(pathfindPosition)
end)

path.WaypointReached:Connect(function(Waypoint, NextWaypoint)
	task.wait(0.1)
	path:Run(pathfindPosition)
end)
path.Error:Connect(function(ErrorType : string)
	warn(ErrorType)

	task.wait(0.1)
	path:Run(pathfindPosition)
end)
path.Trapped:Connect(function(TrapType : string)
	if rake.Monster:GetState() ~= Enum.HumanoidStateType.Climbing then
		path.Jump()
	end
	path:Run(pathfindPosition)
end)

path.Timeout = true
path.Speed = 16
path.Visualize = true
path.Precise = true

I Do path:Run() in a loop

Using only the code given, I can’t figure out what’s the issue. As your monster behaves strange, which it seems like it still chases you even without path being generated (I don’t see visual points appearing sometimes). Also I am unsure how you are implementing the loop. Generally, you shouldn’t use path:Run() in a loop with signals(also calling path:Run()) together, because when using a loop, signals are pointless as you are calling path:Run() in a certain interval anyways. Also how Trapped work is if the monster failed to reach the destination after a certain time, it fires. By calling path:Run() again, the trapped detection for the previous run will be canceled, making it unviable in this case if you are looping the path:Run().

local pathfindPosition = Vector3.new()
local Pathfinding = require(workspace.NoobPath)
local rake = workspace.Rig

local path = Pathfinding.Humanoid(rake, 
	{
		AgentHeight = 4, -- 3
		AgentRadius = 2, -- 2
		AgentCanJump = true,
		AgentCanClimb = true,
		Costs = {
			PathfindAvoid = 9999,
			Truss = 1,
		},
		PathSettings = {
			SupportPartialPath = true,
		},
		WaypointSpacing = 5.5 -- 10
	}
)

path.Reached:Connect(function(Waypoint, IsPartial)
	task.wait(.1)
	path:Run(pathfindPosition)
end)

path.WaypointReached:Connect(function(Waypoint, NextWaypoint)
	task.wait(0.1)
	path:Run(pathfindPosition)
end)
path.Error:Connect(function(ErrorType : string)
	warn(ErrorType)

	task.wait(0.1)
	path:Run(pathfindPosition)
end)
path.Trapped:Connect(function(TrapType : string)
	print("Trapped")
	if rake.Humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then
		path.Jump()
	end
	path:Run(pathfindPosition)
end)

path.Timeout = true
path.Speed = 16
path.Visualize = true
-- path.Precise = true -- Removed due to bad performance and limited usage, does nothing as of now

local first = true

-- Loop implementation A (Can use with signals)
while true do
	task.wait(0.1)
	pathfindPosition = workspace:WaitForChild("grewsxb4").PrimaryPart:GetPivot().Position
	if first then
		-- Run only once, then signals will handle the rest
		path:Run(pathfindPosition)
	end
	first = false
end

-- Loop implementation B (Don't use with signals)
while true do
	task.wait(0.1)
	pathfindPosition = workspace:WaitForChild("grewsxb4").PrimaryPart:GetPivot().Position
	path:Run(pathfindPosition)
end

I tested both Loop A and Loop B, no random jumping occurred.
Please provide me with more details.

1 Like

check dms

This text will be blurred

thank you so much for this module! awesome work :grinning: :grinning:

Proper documentation and a Wally release would be nice.

1 Like

A performance issue exists when you run the code for a certain time. (in my case, 2 or 3 mins of pathfinding would lead to lag in npc movement.

Hi, can you send me the code that produces the issue?

I tested with this script for 11 minutes:

local NoobPath = require(game.ServerStorage.NoobPath)

task.spawn(function()
	while task.wait(60) do
		print(time())
	end
end)

local Guy, JumpDetectConnection = NoobPath.Humanoid(script.Parent, {WaypointSpacing = 10, PathSettings = {SupportPartialPath = true}})

if Guy.Idle then -- Access Character state through .Idle
--	print("Idle")
end

Guy.Reached:Connect(function(Waypoint, IsPartial)
	print("Reached: " .. tostring(Waypoint) .. " | Partial: " .. tostring(IsPartial))
	task.wait(0.1)
	Guy:Run(Guy.Character:GetPivot().Position + Vector3.new(math.random(-100, 100), 0, math.random(-100, 100)))
end)

Guy.WaypointReached:Connect(function(Waypoint, NextWaypoint)
--	print("WaypointReached: " .. tostring(Waypoint) .. " | NextWaypoint: " .. tostring(NextWaypoint))
	Guy:Run()
end)

Guy.Error:Connect(function(ErrorType : string)
	print("Error: ".. ErrorType, Guy.Goal)
	task.wait(0.1)
	Guy:Run()
end)

Guy.Trapped:Connect(function(TrapType : string)
	print("Trapped: ".. TrapType) 
	if script.Parent.Humanoid:GetState() ~= Enum.HumanoidStateType.Climbing then -- Climbing is slower than usual
		Guy.Jump() -- Jump to unstuck
	end

	Guy:Run()
end)

Guy.Timeout = true -- Off by default, it calculate time necessary to travel between Waypoints and Check if the Character arrived after that amount of time, Trapped will be fired if the Character didn't reach Waypoint in time
Guy.Speed = 16 -- 16 by default, used to allow Timeout calculate time necessary to travel between Waypoints
Guy.Visualize = true -- Off by default, basically generate visual spheres to represent Waypoints

Guy:Run(Guy.Character:GetPivot().Position + Vector3.new(math.random(-100, 100), 0, math.random(-100, 100)))
-- Location : Vector3 | BasePart | Model

The Npc’s movement seems fine.

Sorry, I don’t use/know what is Wally, as of the documentation, I will do it soon.

Set any part or all parts of the NPC’s network owner to nil

for i,v in pairs(NPC:GetDescendants()) do
	if v:IsA("BasePart") then
		v:SetNetworkOwner(nil)
	end
end