Hey, so I am trying to make an npc that simply follows the player. The problem I’m having though is that when the npc runs into a wall, it absolutely refuses to jump over it. If I make it a really short wall it jjust runs into the wall and keeps trying to push through it, when I make it a taller wall the npc literally just walks around, even though the wall is still short enough for it to jump over. I’ve tried several things, but it just will not jump and I have no idea why! Below is a video of what’s happening, as well as my script, if anyone knows what’s wrong I’d really appreciate the help.
wait(3)
local pathfindingService = game:GetService("PathfindingService")
local fightingNpcs = workspace:WaitForChild("Map"):WaitForChild("FightingNPCs")
local RunS = game:GetService("RunService")
local function handleNpc(npc)
if npc ~= nil then
if npc:FindFirstChild("HumanoidRootPart") ~= nil then
local waypoints = nil
local function MoveTONextWaypoint()
local waypoint = waypoints[2]
if waypoint == nil then
print(waypoints)
--[[runAnimation:Stop()]]
return
else
if waypoint.Action == Enum.PathWaypointAction.Jump then
print("IT SHOULD BE JUMPING")
npc.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
else
print(waypoint.Action)
end
npc.Humanoid:MoveTo(waypoint.Position)
end
end
npc.Humanoid.MoveToFinished:Connect(function(reached)
if reached == false then print("Has not reached")--[[npc:SetPrimaryPartCFrame(CFrame.new(waypoints[waypointIndex].Position))]] return end
MoveTONextWaypoint()
end)
npc.AttributeChanged:Connect(function(attribute)
--if attribute == "Destination" then
if npc:GetAttribute("Target") ~= nil then
local targetChar = workspace:FindFirstChild(npc:GetAttribute("Target"))
if targetChar ~= nil then
local targetHrp = targetChar:FindFirstChild("HumanoidRootPart")
--local destination = npc:GetAttribute("Destination")
if targetHrp ~= nil then
local destination = targetHrp.Position
if (workspace.CurrentCamera.Focus.Position - destination).Magnitude > 500 then
--npc.Parent = game.ReplicatedStorage
--npc:SetPrimaryPartCFrame(CFrame.new(destination))
else
--npc.Parent = npc
local path = pathfindingService:CreatePath({
["AgentRadius"] = 3,
["AgentHeight"] = 5,
["AgentCanJump"] = true,
["WaypointSpacing"] = 4,
["Costs"] = {
["Water"] = 20
}
})
local success, returned = pcall(path.ComputeAsync, path, npc.HumanoidRootPart.Position, destination)
if success == true and path.Status == Enum.PathStatus.Success then
--print("Computed new path")
--print(destination)
--print(path.Instance)
--runAnimation:Play()
waypoints = path:GetWaypoints()
MoveTONextWaypoint()
--print("Npc should be moving")
else
print("Path failed")
print(success)
print(path.Status)
path:ComputeAsync(npc:FindFirstChild("HumanoidRootPart").Position, destination)
--npc:SetPrimaryPartCFrame(CFrame.new(destination))
end
end
else
print("Target hrp is nil")
end
end
else
end
end)
end
end
end
local connection = nil
for i, folder in ipairs(fightingNpcs:GetChildren()) do
if folder.Name == "TestFolder" then
for i, npc in ipairs(folder:GetChildren()) do
handleNpc(npc)
end
elseif folder.Name == "Platforms" then
local allPlatforms = folder:GetChildren()
for i, platform in ipairs(allPlatforms) do
for i, spawnBlock in ipairs(platform:GetChildren()) do
if spawnBlock.Name == "SpawnBlock" then
if #(spawnBlock:GetChildren()) > 0 then
for i, npc in ipairs(spawnBlock:GetChildren()) do
handleNpc(npc)
end
end
end
end
end
else
print(folder.Name)
print("IS THE FOLDER")
for i, spawnBlock in ipairs(folder:GetChildren()) do
if #(spawnBlock:GetChildren()) > 0 then
print(#(spawnBlock:GetChildren()))
for i, npc in ipairs(spawnBlock:GetChildren()) do
handleNpc(npc)
end
end
end
end
end
Nope, it’s not printing at all. It’s jump power is 50, and I’ve even tried using jumpheight instead to see if that would change anything. Both gave the same result. In the video, you’ll see that the waypoints are red when going from one side of the wall to the other, what does that mean? I assumed it meant it was blocked but not even connecting a blocked event has worked.
I am confused as to what you mean, I do tell it to jump if the waypoint action is jump right here:
if waypoint.Action == Enum.PathWaypointAction.Jump then
print("IT SHOULD BE JUMPING")
npc.Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
else
print(waypoint.Action)
end
It’s even supposed to print that the npc should be jumping, the waypoint action is simply never jump and it’s always walk. So I’m not entirely sure what you mean, if you could elaborate that would be nice. And I’ve read the documentation.
Your script is very unoptimized that might cause inner calculation overload and cause the pathfidning AI to not generate right, You should follow the pathfinding guide in roblox official tutorial page.
Pathfiding itseld shouldnt be more that 20 lines of code
Pathfinding although simple isnt all thats going on there from what I read.
Also for OP , The code looks fine at least to me, but that pcall looks a bit strange to me. i do beleive path.ComputeAsync is meant to be path:ComputeAsync(StartPosition, EndPosition). Maybe that could be your issue?
I have never seen it done the way you did it here.
I mean if you disregard the print statements and comments then everything that utilizes pathfinding is in fact, pretty much only 20 lines of code. The other stuff you see is more-so set-up for other functionalities. I do believe that there is some optimization issues going on though, because I recently discovered that my waypoints were, I guess I should say “un-aligned” (If that’s even a word). Like, the npc was “reading” a waypoint that it should not have been currently reading, if that makes sense at all (And sorry if it doesn’t). That being said, I decided to change the MoveTONextWaypoint() function and had it check the waypoints and change them accordingly:
local function MoveTONextWaypoint()
waypointIndex += 1
if waypoints[waypointIndex] ~= nil then
local waypoint = waypoints[waypointIndex]
if waypoint == nil then
waypoint = waypoints[waypointIndex - 1]
end
if waypoint.Position == lastPosition then
waypoint = waypoints[waypointIndex + 1]
end
if waypoint == nil then
return
else
if waypoint.Action == Enum.PathWaypointAction.Jump then
npc.Humanoid.Jump = true
else
end
npc.Humanoid:MoveTo(waypoint.Position)
lastPosition = waypoint.Position
npc.Humanoid.MoveToFinished:Wait()
end
end
end
And I modified the rest of my script to:
npc.Humanoid.MoveToFinished:Connect(function(reached)
if reached == false then print("Has not reached") return end
MoveTONextWaypoint()
end)
npc.AttributeChanged:Connect(function(attribute)
if npc:GetAttribute("Target") ~= nil then
local targetChar = workspace:FindFirstChild(npc:GetAttribute("Target"))
if targetChar ~= nil then
local targetHrp = targetChar:FindFirstChild("HumanoidRootPart")
if targetHrp ~= nil then
local destination = targetHrp.CFrame.Position + Vector3.new(0, 0, -1)
if (workspace.CurrentCamera.Focus.Position - destination).Magnitude > 500 then
else
local path = pathfindingService:CreatePath({
["AgentRadius"] = 3,
["AgentHeight"] = 5,
["AgentCanJump"] = true,
["WaypointSpacing"] = 4
})
local success, returned = pcall(path.ComputeAsync, path, npc.HumanoidRootPart.Position, destination)
if success == true and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
if waypoints ~= nil then
waypointIndex = 1
MoveTONextWaypoint()
end
else
print("Path failed")
print(success)
print(path.Status)
path:ComputeAsync(npc:FindFirstChild("HumanoidRootPart").Position, destination)
end
end
else
print("Target hrp is nil")
end
end
else
end
end)
It now jumps over the shorter wall, but it still chooses to walk around the taller wall instead, which is rather interesting to me. I believe it has something to do with the pcall as @09glich2 mentioned, though I’m also going to try to follow the documentation’s style a little more as well. I hadn’t done so because directly following it was not working for what I need the npc to do, I’ve been trying to implement it as best as I could.
Just attempted to do without the pcall, and I received the same results. Though in the process, I tried standing on the wall, and discovered that the path is not being created when the player character is at a position of higher elevation. And when approaching the player FROM a higher elevation, it jumps in the same spot several times before finally coming down. Do you guys know what might be the reason for this?