[Solved] Pathfinding Problem

Yeah I totally get what you’re saying now but the code just isn’t compatible for that at the moment. The walk to would cause it to not work because walk to is calling attack which then moves it, it’s weird. I’m not too well versed in this either and I certainly wouldn’t have a clue how to make an entire pathfinding script myself, so with that said, this is all I’ve got to work with.

This is taking a lot longer because you’re being very vague. If I don’t know how it’s pathfinding incorrectly, how can I figure out what your problem is?

You say something like this, but I don’t know what it means in terms of the NPC. How does the behavior of the NPC change? You don’t tell me, so I have to ask specifically. You need to explain details like that without having to be asked, so it’s faster to respond and help you.

2 Likes

Oh ye I didn’t see… Mm wouldn’t it be better to have a function just for movement and then a function to detect target ? so that you could call your pathfinding movement without actually looping the attack if you already found a target ( idk if you see what I mean, I’m not very clear about it myself :joy: )

I apologize kind sir! I thought that the picture explained everything. The NPC walks to the waypoints, it can even try to jump now, and instead of going around to the other side where it can walk up the ramp, it tries to jump and gets stuck instead. We want the NPC to take the path that it can walk up the ramp, not be trying to walk straight to the waypoint regardless of there being other ways to get to the waypoint that don’t require any jumping!

Try to copy paste the ROBLOX official tutorial pathfinding

1 Like

when you try to visualize the pathfinding waypoints, do they also go for the jump or the ramp ? if for the jump then it’s likely that a parameter in the pathfinding need tweaks

In that case, you can increase how “expensive” it thinks jumping is. Also, I just noticed in your code, you are not even setting your Agent Parameters?

pathParams is literally unused.

local pathParams = {
	AgentHeight = 6,
	AgentRadius = 2,
	AgentCanJump = true,
	
	Costs = {
		-- Jumping is now equivalent to walking 15 studs
		-- Increase this value further if they still prefer to 
		-- jump rather than walk
		Jump = 15
	}
}

local path = PathfindingService:CreatePath(pathParams)

local function getPath(destination)
	path:ComputeAsync(stranger.HumanoidRootPart.Position, destination.Position, pathParams)
	return path
end

There’s also no reason to call :CreatePath more than once if you’re never going to change your Parameters.

2 Likes

They are just going for the jump. They never ever try to take the correct path to the waypoints

Very interesting. This does completely prevent him from getting stuck. It does help a lot don’t get me wrong. But does it fix our problem? No. He still jumps up there instead of taking the other way around

If you set AgentCanJump to false, does the NPC take the route you want it to take?

1 Like

Yes. We are getting close. Fully solved the waypoints problem. Now how do we fix the attack? I have no clue how to pathfind to targets.

Continuous pathfinding is very annoying and complicated and I would recommend you just use something like SimplePath:

Then, you can just do path:Run(target.HumanoidRootPart.Position) in your attack function, and get rid of your pathfinding for-loop.

1 Like

That’s your opinion. I would really like to replace the attack function with your pathfinding version of it so I can solve this problem for good and mark your answer as solution. If you could please annotate how it works so everyone can understand it, would be a huge help to all of us.

Here is a modified version of your code using SimplePath for pathfinding.

local PathfindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

local stranger = script.Parent
local humanoid = stranger.Humanoid
local rootPart = stranger.HumanoidRootPart

local raycastParams = RaycastParams.new()

local pathParams = {
	AgentHeight = 6,
	AgentRadius = 2,
	AgentCanJump = true,
	Costs = {
		-- Jumping is equivalent to walking 50 studs
		Jump = 50
	}
}

-- Create our Path with SimplePath
local path = require(script.SimplePath).new(stranger, pathParams)

stranger.PrimaryPart:SetNetworkOwner(nil)

raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = { stranger }

local function canSeeTarget(target)
	local direction = target.HumanoidRootPart.Position - rootPart.Position

	local result = workspace:Raycast(rootPart.Position, direction, raycastParams)

	if result then
		local hit = result.Instance
		if hit and hit:IsDescendantOf(target) then
			-- Something was in the way, but it was just our Target
			return true
		else
			-- Something was in the way, but it wasn't our Target
			return false
		end
	else
		-- Nothing in the way
		return true
	end
end

local function findTarget()
	local players = Players:GetPlayers()
	local nearestTarget = nil
	local maxDistance = 75
	
	for _, player in players do
		local target = player.Character
		
		if target and target.PrimaryPart then
			local target = player.Character
			local distance = (rootPart.Position - target.HumanoidRootPart.Position).Magnitude
			
			if distance < maxDistance and canSeeTarget(target) then 
				nearestTarget = target
				maxDistance = distance
			end
		end
	end

	return nearestTarget
end

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

	if distance > 3 then
		path:Run(target.HumanoidRootPart.Position)
	else
		target.Humanoid.Health = 0
	end
end

local function patrol()
	-- Recognize targets
	local target = findTarget()
	
	if target then
		attack(target)
		-- Don't worry about patrolling when we're hunting someone down
		return
	end
	
	-- "Idle" means we are not moving.
	-- When `path:Run` is called, it sets it's `Status` to
	-- "Active". Then, when the Destination is reached, it is set back to "Idle".
	-- We don't want to change which Waypoint we're moving towards while
	-- we are moving towards it, so we can use `Status` to make sure we
	-- stick to 1 Waypoint
	if path.Status == "Idle" then
		local waypoints = workspace.Waypoints:GetChildren()
		local randomNum = math.random(1, #waypoints)
		
		path:Run(waypoints[randomNum].Position)
	end
end

while true do
	patrol()
	-- There's no point updating every frame, so it's just an
	-- easy performance optimization that won't have any impact besides
	-- a very small "reaction time" that you probably won't even notice.
	task.wait(0.2)
end
1 Like

I guess I have no choice but to try this. I immediately encountered problems after trying to use the continuous pathfinding

1 Like

Line 101 is calling :Run and giving it something that doesn’t have a position. What is on Line 101?

path:Run(waypoints.Position)
1 Like

Oops :grimacing: That should be

path:Run(waypoints[randomNum].Position)

Every single time I think that I’ve finally fixed everything, nope. It gets stuck the same way every single time I move my npc out far out enough. It’s funny how even just in my super basic game that has barely anything in it, things still don’t even work right. I will send a video.