I’ve been trying to create a pathfinding script that’ll chase the nearest player for the past two days, and it’s been successful for the most part (especially considering this is my first time seriously messing with it). However, I’m stumped when it comes to the problem I discovered a few hours ago.
The problem is that the ai seems to have its final waypoint as the player’s previous position, making it stop for just a moment. This makes it look stuttery and makes it impossible for the ai to catch the player if they’re moving when it should as it is faster than the player.
Here’s a video of the issue in question:
I suspect the issue arises from the path being computer in the while loop. However, I’ve tried to remove it from the while loop and can’t seem to even make the ai move after doing so. I’ve tried a whole bunch of other solutions that did not have any different effect either.
Here is my script:
Pathfinding Script
local human = script.Parent:WaitForChild("Humanoid")
local humanRootPart = script.Parent:WaitForChild("HumanoidRootPart")
local PathfindingService = game:GetService("PathfindingService")
local Path = PathfindingService:CreatePath()
script.Parent.PrimaryPart:SetNetworkOwner(nil)
local moving = false
local function findTarget()
local Players = game:GetService("Players")
local MAX_DISTANCE = 200
local nearestTarget
for index, player in pairs(Players:GetPlayers()) do
if player.Character then
local target = player.Character
local distance = (humanRootPart.Position - target.HumanoidRootPart.Position).magnitude
if distance < MAX_DISTANCE then
nearestTarget = target
MAX_DISTANCE = distance
end
end
end
return nearestTarget
end
local currentWaypointIndex = 0
local waypoints = {}
local function moveToNextWaypoint()
currentWaypointIndex += 1
if currentWaypointIndex > #waypoints then
moving = false
return
end
if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
human:ChangeState(Enum.HumanoidStateType.Jumping)
end
human:MoveTo(waypoints[currentWaypointIndex].Position)
end
human.MoveToFinished:Connect(moveToNextWaypoint)
while true do
local target = findTarget()
if target ~= nil then
local targetPos = target.PrimaryPart.Position
Path:ComputeAsync(humanRootPart.Position, targetPos)
currentWaypointIndex = 1
waypoints = Path:GetWaypoints()
if moving == false then
moving = true
moveToNextWaypoint()
end
else
if currentWaypointIndex >= 1 then
moving = false
waypoints = {}
currentWaypointIndex = 0
end
wait()
end
end
I have no idea how to create any type of AI that relates to this, but instead of bringing the AIs character to the back of the player, you could perhaps change the script to make it get to the nearest players humanoid location instead?
I’m gonna give up for tonight since I’ve been at this for a couple of hours now with a few short breaks. I’ll leave a link to this post here for myself to see in the morning.
Tried it out using R15, the short pause stopped but the character seems to jump now Instead maybe it’s detecting the leg as an obstacle and recalculates the path which causes the stop? I honestly have no Idea of Path finding though. Hope you’ll find the error!
Will this work, Doesn’t wait() default to 1 - 0.1 seconds?
local human = script.Parent:WaitForChild("Humanoid")
local humanRootPart = script.Parent:WaitForChild("HumanoidRootPart")
local PathfindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")
local Path = PathfindingService:CreatePath()
script.Parent.PrimaryPart:SetNetworkOwner(nil)
local moving = false
local function findTarget()
local Players = game:GetService("Players")
local MAX_DISTANCE = 200
local nearestTarget
for index, player in pairs(Players:GetPlayers()) do
if player.Character then
local target = player.Character
local distance = (humanRootPart.Position - target.HumanoidRootPart.Position).magnitude
if distance < MAX_DISTANCE then
nearestTarget = target
MAX_DISTANCE = distance
end
end
end
return nearestTarget
end
local currentWaypointIndex = 0
local waypoints = {}
local function moveToNextWaypoint()
currentWaypointIndex += 1
if currentWaypointIndex > #waypoints then
moving = false
return
end
if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
human:ChangeState(Enum.HumanoidStateType.Jumping)
end
human:MoveTo(waypoints[currentWaypointIndex].Position)
end
human.MoveToFinished:Connect(moveToNextWaypoint)
RunService.Stepped:Connect(function()
local target = findTarget()
if target ~= nil then
local targetPos = target.PrimaryPart.Position
Path:ComputeAsync(humanRootPart.Position, targetPos)
currentWaypointIndex = 1
waypoints = Path:GetWaypoints()
if moving == false then
moving = true
moveToNextWaypoint()
end
else
if currentWaypointIndex >= 1 then
moving = false
waypoints = {}
currentWaypointIndex = 0
end
end
end)
Then make a cooldown(create a special thread for path generating) for creating a new path and if the path doesn’t exist then just follow the player instead of points.
So after the global value of path will be loaded just tell the pathfinding to find closest points to the creature and player.
Find closest point which isn’t intersecting with the creature’s distance between player.
And don’t change the direction sharply, it looks unrealistic
Get all points in the yellow area and find the closest one to the chaser (chaser is red and the player is blue)