-
What do you want to achieve? uh so i made a pathfinding npc that follows nearest player, i expect it to be optimized
-
What is the issue? Its not optimized and i get the error when i leave and causes lag
Workspace.NPC.FollowSystem:50: Script timeout: exhausted allowed execution time
-
What solutions have you tried so far? I looked in dev forum and no post could help me
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local enemy = script.Parent
local humanoid = enemy:FindFirstChildOfClass("Humanoid")
if enemy.PrimaryPart then
enemy.PrimaryPart:SetNetworkOwner(nil)
else
warn(enemy.Name, "doesn't have a PrimaryPart set.")
return
end
local animSaves = enemy:FindFirstChild("AnimSaves")
if animSaves then
animSaves:Destroy()
end
local function GetNearestPlayer()
local nearestPlayer, shortestDistance = nil, math.huge
for _, player in pairs(Players:GetPlayers()) do
local character = player.Character or player.CharacterAdded:Wait()
if character then
local primaryPart = character:WaitForChild("HumanoidRootPart") or character.PrimaryPart
if primaryPart then
local distance = (enemy.PrimaryPart.Position - primaryPart.Position).Magnitude
if distance < shortestDistance then
shortestDistance = distance
nearestPlayer = player
end
else
warn(player.Name, "'s character does not have a PrimaryPart!")
end
else
warn(player.Name, "doesn't have a character loaded!")
end
end
return nearestPlayer
end
local function positionCheck(position)
local partAtPosition = workspace:FindPartOnRayWithIgnoreList(Ray.new(position, Vector3.new(0, -10, 0)), {enemy})
return partAtPosition ~= nil
end
local function FollowNearestPlayer()
local nearestPlayer = GetNearestPlayer()
if nearestPlayer and nearestPlayer.Character and nearestPlayer.Character:FindFirstChild("HumanoidRootPart") or nearestPlayer and nearestPlayer.Character and nearestPlayer.Character.PrimaryPart then
local playerPosition = nearestPlayer.Character:WaitForChild("HumanoidRootPart").Position or nearestPlayer.Character.PrimaryPart.Position
local randomOffset = Vector3.new(math.random(-10, 10), 0, math.random(-10, 10))
local targetPosition = playerPosition
-- print("Enemy Position:", enemy.PrimaryPart.Position)
-- print("Player Position:", playerPosition)
-- print("Target Position:", targetPosition)
if not positionCheck(enemy.PrimaryPart.Position) then
warn("Enemy is in the air!")
return nil
end
if not positionCheck(targetPosition) then
warn("Target is in the air or flying..")
return nil
end
local path = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = true,
AgentMaxSlope = 45,
AgentCanClimb = true,
})
local success, errorMessage = pcall(function()
path:ComputeAsync(enemy.PrimaryPart.Position, targetPosition)
end)
if success then
-- print("Path successfully computed")
return path
else
warn("Failed to compute path: ", errorMessage)
end
else
-- warn("Player primary part is nil or not loaded..")
end
return nil
end
local function moveToPlayer()
local nextOffsetTime = tick() + math.random(3, 7)
while enemy and enemy.Parent and humanoid do
local path
local currentTick = tick()
if currentTick >= nextOffsetTime then
path = FollowNearestPlayer()
nextOffsetTime = currentTick + math.random(3, 7)
else
path = FollowNearestPlayer()
end
if path then
local waypoints = path:GetWaypoints()
for _, waypoint in pairs(waypoints) do
if humanoid then
humanoid:MoveTo(waypoint.Position)
end
end
else
-- task.wait(1)
end
end
end
if enemy then
task.wait(20)
moveToPlayer()
end