So I am having this issue where I simply locally highlight npcs I click on, but for some very random reason, when I do that the server script controlling npc’s pathfinding starts to weirdly lag, before I will continue, let me say that there is no error or anything in output and the path for npc IS FOUND so its not like it recalculates or something. The thing is, the npc “lags” after every waypoint, but it DOES NOT happen when the local script is disabled. Here are clips for better understanding:
Clip where npc lags and I have local script enabled:
Clip where npc works normally with local script disabled:
the local script I am using:
local player = game:GetService("Players").LocalPlayer
local mouse = player:GetMouse()
local userInputService = game:GetService("UserInputService")
local connectionInputBegan = nil
local connectionInputEnded = nil
local userInput = nil
local isActivated = false
local startMousePosition = nil
local isMultipleSelecting = false
local listOfHighlightes = {}
local selectedNPCs = {}
local function addHighlight(object, color)
local highlight = Instance.new("Highlight")
highlight.FillColor = color.Color
highlight.FillTransparency = 0.9
highlight.OutlineColor = color.Color
table.insert(listOfHighlightes, highlight)
highlight.Parent = object
end
local function moveMause()
if isActivated == false then return end
if (startMousePosition - userInputService:GetMouseLocation()).Magnitude > 25 then
isMultipleSelecting = true
end
end
local function inputEnded(input, processed)
if userInput ~= input then return end
userInput = nil
isActivated = false
connectionInputEnded:Disconnect()
startMousePosition = nil
print("Deactivated")
if not userInputService:IsKeyDown(Enum.KeyCode.LeftShift) then
for i,v in pairs(listOfHighlightes) do
v:Destroy()
end
for i,v in pairs(selectedNPCs) do
table.clear(selectedNPCs)
end
end
if isMultipleSelecting == false then
local mouseHit = mouse.Target
if mouseHit.Parent.Name ~= "Workspace" and mouseHit.Parent:FindFirstChild("Humanoid") then
--mouseHit.Parent:FindFirstChild("Team").Value == game:GetService("ReplicatedStorage"):WaitForChild("UserData"):FindFirstChild(player.Name):WaitForChild("Team").Value
table.insert(selectedNPCs, mouseHit.Parent)
for i,v in pairs(selectedNPCs) do
addHighlight(v, v:FindFirstChild("Team").Value)
end
end
end
isMultipleSelecting = false
end
local function inputBegan(input, processed)
if userInput ~= nil then return end
if processed == true then return end
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
startMousePosition = userInputService:GetMouseLocation()
userInput = input
isActivated = true
connectionInputEnded = userInputService.InputEnded:Connect(inputEnded)
print("Activated")
end
mouse.Move:Connect(moveMause)
connectionInputBegan = userInputService.InputBegan:Connect(inputBegan)
I think with this I can cay for sure its not server script’s fault but I will put it here anyway because I am sure someone will ask for it, but I am saying it in front that its pretty messy:
local humanoid = script.Parent:WaitForChild("Humanoid")
local npcRoot = script.Parent:WaitForChild("HumanoidRootPart")
local team = script.Parent:WaitForChild("Team")
local inDanger = script.Parent:WaitForChild("inDanger")
local pathService = game:GetService("PathfindingService")
local stats = script.Parent.stats:GetChildren()
local walkStatus = 0
local requireToLook = true
local FoodGatherAnim = humanoid.Animator:LoadAnimation(script.Parent.Animations:WaitForChild("FoodSource"))
local waveAnim = humanoid.Animator:LoadAnimation(script.Parent.Animations:WaitForChild("WaveAnim"))
local PhysicsService = game:GetService("PhysicsService")
local blockedConnection
local nextWaypointIndex
local home = workspace:WaitForChild("Home")
task.wait(2)
for _, child in ipairs(script.Parent:GetChildren()) do
if child:IsA("MeshPart") or child:IsA("Part") or child:IsA("BasePart") then
PhysicsService:SetPartCollisionGroup(child, "npcGroup")
end
end
local function getStat(stat)
for i,v in pairs(stats) do
if v.Name == stat then
return v
end
end
end
local GatherType = getStat("GatherType")
local function findNearestGather(object)
local currentNearest = nil
local objects = workspace:FindFirstChild(object)
if objects == nil then
return nil
end
objects = objects:GetChildren()
for i,v in pairs(objects) do
if v:FindFirstChild("Amount").Value > 0 then
if currentNearest == nil then
currentNearest = v
elseif (npcRoot.Position - v.PrimaryPart.Position).Magnitude < (npcRoot.Position - currentNearest.PrimaryPart.Position).Magnitude then
currentNearest = v
end
end
end
return currentNearest
end
local function pathFind(destination)
requireToLook = true
if walkStatus ~= 0 then walkStatus = 2 end
repeat task.wait(0.1) until walkStatus == 0
nextWaypointIndex = 1
walkStatus = 1
local path = pathService:CreatePath({
AgentCatJump = false
})
local success, errorMessage = pcall(function()
path:ComputeAsync(npcRoot.Position, destination.Position - CFrame.new(npcRoot.Position, destination.Position).LookVector * 4)
end)
if success and path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
if blockedWaypointIndex >= nextWaypointIndex then
blockedConnection:Disconnect()
print("hitler")
pathFind(destination)
end
end)
for i, waypoint in ipairs(waypoints) do
if walkStatus == 2 then
walkStatus = 0
break
end
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
nextWaypointIndex += 1
end
walkStatus = 0
elseif path.Status == Enum.PathStatus.NoPath then
waveAnim:Play()
task.wait(1.5)
waveAnim:Stop()
walkStatus = 0
end
end
local function isFull(resource)
if resource == "FoodSource" then
local maxfood = getStat("Food")
local food = getStat("MaxFood")
if maxfood.Value == food.Value then
return true
else
return false
end
elseif resource == "WoodSource" then
local maxfood = getStat("Wood")
local food = getStat("MaxWood")
if maxfood.Value == food.Value then
return true
else
return false
end
end
end
local function gather(Source)
if requireToLook == true then
npcRoot.CFrame = CFrame.lookAt(npcRoot.Position, Source.PrimaryPart.Position)
requireToLook = false
end
if GatherType.Value == "FoodSource" then
FoodGatherAnim:Play()
elseif GatherType.Value == "WoodSource" then
FoodGatherAnim:Play()
end
task.wait(getStat("GatherTime").Value)
if Source:FindFirstChild("Amount").Value <= 0 then
return
end
Source:FindFirstChild("Amount").Value -= 1
if GatherType.Value == "FoodSource" then
local food = getStat("Food")
food.Value += 1
elseif GatherType.Value == "WoodSource" then
local wood = getStat("Wood")
wood.Value += 1
end
end
local function returnResources()
local food = getStat("Food")
food.Value = 0
local wood = getStat("Wood")
wood.Value = 0
end
local function mainLoop()
local Source = findNearestGather(GatherType.Value)
if inDanger.Value == true then
pathFind(home)
elseif isFull(GatherType.Value) == false then
if Source ~= nil and (npcRoot.Position - Source.PrimaryPart.Position).Magnitude > 6 then
pathFind(Source.PrimaryPart)
end
if (npcRoot.Position - Source.PrimaryPart.Position).Magnitude < 7 then
gather(Source)
end
elseif isFull(GatherType.Value) == true then
pathFind(home)
if (npcRoot.Position - home.Position).Magnitude < 5 then
returnResources()
end
end
end
while true do
mainLoop()
end