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.
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 )
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
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.
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?
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.
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
I guess I have no choice but to try this. I immediately encountered problems after trying to use the continuous pathfinding
Line 101 is calling :Run
and giving it something that doesn’t have a position. What is on Line 101?
path:Run(waypoints.Position)
Oops 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.