As you can see, while moving, it occasionally twitches. This didn’t happen if I compute paths once the humanoid as reached its destination, but i’m doing a chase NPC.
local AIFolder=workspace:WaitForChild("AI")
local Players=game:GetService("Players")
local PathfindService=game:GetService("PathfindingService")
local RunService=game:GetService("RunService")
local CachedHumanoidRootParts={}
Players.PlayerAdded:Connect(function(localplr)
localplr.CharacterAdded:Connect(function(char)
CachedHumanoidRootParts[localplr]=char:FindFirstChild("HumanoidRootPart")
end)
end)
Players.PlayerRemoving:Connect(function(localplr)
CachedHumanoidRootParts[localplr]=nil
end)
local CurrentPathsInProgress={}
local NPCstats={}
local function VisualizePath(path, npc)
if npc:FindFirstChild("DebugPath") then
npc.DebugPath:Destroy()
end
local folder=Instance.new("Folder")
folder.Name="DebugPath"
folder.Parent=npc
for i, waypoint in ipairs(path:GetWaypoints()) do
local part=Instance.new("Part")
part.Size=Vector3.new(0.5, 0.5, 0.5)
part.Shape=Enum.PartType.Ball
part.Color=Color3.fromRGB(0, 255, 0)
part.Anchored=true
part.CanCollide=false
part.Position=waypoint.Position
part.Parent=folder
if waypoint.Action==Enum.PathWaypointAction.Jump then
part.Color=Color3.fromRGB(255, 0, 0)
end
end
end
local function ComputeNewPath(HRP, destination, hum, npc)
CurrentPathsInProgress[npc]=nil
local path=PathfindService:CreatePath({
AgentRadius=2,
AgentHeight=5,
AgentCanJump=true,
AgentJumpHeight=7.5,
AgentMaxSlope=45,
})
path:ComputeAsync(HRP.Position, destination.Position)
if path.Status==Enum.PathStatus.Success then
CurrentPathsInProgress[npc]=true
VisualizePath(path, npc)
task.spawn(function()
for _, waypoint in ipairs(path:GetWaypoints()) do
if not CurrentPathsInProgress[npc] then break end
if waypoint.Action==Enum.PathWaypointAction.Jump then
hum:ChangeState(Enum.HumanoidStateType.Jumping)
end
hum:MoveTo(waypoint.Position)
hum.MoveToFinished:Wait()
end
CurrentPathsInProgress[npc]=nil
end)
else
CurrentPathsInProgress[npc]=nil
end
end
local LastCheck=tick()
local CheckInterval=.5
local CheckRadius=200
RunService.Heartbeat:Connect(function(dt)
if tick()-LastCheck>=CheckInterval then
LastCheck=tick()
for i, npc in pairs(AIFolder:GetChildren()) do
if npc:IsA("Model") and npc:FindFirstChildOfClass("Humanoid") then
local NPChum=npc:FindFirstChild("Humanoid")
local NPChumRoot=npc:FindFirstChild("HumanoidRootPart")
for plr,humroot in pairs(CachedHumanoidRootParts) do
local dist=(humroot.Position-NPChumRoot.Position).Magnitude
if dist<=CheckRadius then
ComputeNewPath(NPChumRoot, humroot, NPChum,npc)
end
end
end
end
end
end)
I’ve looked through other posts but couldn’t find a solution.
Thanks, this seems to work a lot better. I’ve noticed a problem though. If im near the NPC, it starts going back and forth. Like it starts walking away, then turning back and walking towards me, then turning aaway and walking away and etc etc. I’ve tried implementing distance checks to stop the NPC from moving within a certain distance, but it just doesn’t work for whatever reason
local function ComputeNewPath(HRP, destination, hum, npc)
CurrentPathsInProgress[npc]=nil
local path=PathfindService:CreatePath({
AgentRadius=2,
AgentHeight=5,
AgentCanJump=true,
AgentJumpHeight=7.5,
AgentMaxSlope=45,
})
path:ComputeAsync(HRP.Position, destination.Position)
if path.Status==Enum.PathStatus.Success then
CurrentPathsInProgress[npc]=true
local waypointindex=1
VisualizePath(path, npc)
local waypoints=path:GetWaypoints()
task.spawn(function()
local waypoints = path:GetWaypoints()
local currentWaypointIndex = 1
local moveDirection = Vector3.new(0, 0, 0)
local lastPosition = HRP.Position
local lastUpdate = os.clock()
local arrivalThreshold = 2
local stuckThreshold = 0.5
local moveSpeed = hum.WalkSpeed
local rotationSpeed = 12
while currentWaypointIndex <= #waypoints do
local currentWaypoint = waypoints[currentWaypointIndex]
local currentPosition = HRP.Position
local dist=(HRP.Position-destination.Position).Magnitude
if currentWaypoint.Action == Enum.PathWaypointAction.Jump or hum.Sit == true then
hum.Jump = true
task.wait(0.5)
end
local toWaypoint = (currentWaypoint.Position - currentPosition) * Vector3.new(1, 0, 1)
local distance = toWaypoint.Magnitude
if distance <= arrivalThreshold then
currentWaypointIndex += 1
if currentWaypointIndex > #waypoints or dist<=CloseThreshold then break end
continue
end
if os.clock() - lastUpdate > stuckThreshold then
if (currentPosition - lastPosition).Magnitude < 0.1 then
return true
end
lastPosition = currentPosition
lastUpdate = os.clock()
end
moveDirection = toWaypoint.Unit
hum:Move(moveDirection)
task.wait()
end
hum:Move(Vector3.new(0, 0, 0))
CurrentPathsInProgress[npc]=nil
return true
end)
else
CurrentPathsInProgress[npc]=nil
StunnedNPCS[npc]=true
task.delay(2,function()
StunnedNPCS[npc]=false
end)
end
end
The distance checks also are not desired since this means that they can stun the npc by just staying close to it.
I have broken this problem down to tears. The best I’ve ever been able to get it to work was to have them know the next point before they reach the one they are going to. It’s in that moment of getting the next point to go to that they stutter from time to time.
Yeah the turning back issue is because while the npc is walking the first path point spawns behind it, try to offset the origin based on rootpart linear velocity unit