Hey,
I have this Dijkstra pathfinding algorithm and it works fine and all no lag or whatsoever when I play in studio but online it's acting really buggy.
The NPC doesn't walk like a human it sort of lags forwards. Here, if you watch this gif you'll probably see what I mean.
This is all on the server side so other players can see the same NPC. The question being how would I reduce this amount of lag/bugginess?
Gif: https://gyazo.com/886652cda6b734a19e9ad806ba7ce3f6
Here's my module script:
local module = {}
module.__index = module
local Nodes = workspace.Tiles
local Spawn
local PhysicsService = game:GetService("PhysicsService")
local playerCollisionGroupName = "NPCs"
PhysicsService:CreateCollisionGroup(playerCollisionGroupName)
PhysicsService:CollisionGroupSetCollidable(playerCollisionGroupName, playerCollisionGroupName, false)
local function Tablecontains(table, element)
for i,v in pairs(table) do
if table == element then
return true
end
end
return false
end
local function setCollisionGroupRecursive(object)
if object:IsA("BasePart") then
PhysicsService:SetPartCollisionGroup(object, playerCollisionGroupName)
end
for _, child in ipairs(object:GetChildren()) do
setCollisionGroupRecursive(child)
end
end
local function CreatePool(Type)
local AssetsGuest = game.ReplicatedStorage.AssetsGuest
local IslandGuest = AssetsGuest[Type]:Clone()
IslandGuest.Parent = workspace.LocalDump
IslandGuest.Head.Ui.Txt.Text = IslandGuest.Name
local SpawnPositions = workspace.Tiles
local Index = math.random(1, #SpawnPositions:GetChildren())
local ChosenPoint = SpawnPositions:GetChildren()[Index]
Spawn = ChosenPoint
IslandGuest:SetPrimaryPartCFrame(CFrame.new(ChosenPoint.Position) + Vector3.new(0, 5, 0))
return IslandGuest
end
function module:New(Type)
local self = {
Model = CreatePool(Type),
Start = Spawn,
}
setmetatable(self, module)
self.RootPart = self.Model:FindFirstChild("HumanoidRootPart")
self.Humanoid = self.Model:FindFirstChild("Humanoid")
setCollisionGroupRecursive(self.Model)
return self
end
local WaitForMoveToFinished
do
local RunService = game:GetService("RunService")
function WaitForMoveToFinished(self, position, timeout)
local initTime = tick()
timeout = timeout or 1e3
local position2D = Vector3.new(position.X, self.RootPart.Position.Y, position.Z)
while ((self.RootPart.Position - position2D).magnitude > 2 and tick() - initTime < timeout) do
RunService.Heartbeat:Wait()
end
end
end
local function Dijkstra(nodes, start, target)
local dist, prev = {},{}
local Q = {}
for i,v in ipairs(nodes:GetChildren()) do
dist[v] = math.huge
Q[v] = true
end
dist[start] = 0
while next(Q) do
local u
local least = math.huge
for v, i in pairs(Q) do
if dist[v] < least then
least = dist[v]
u = v
end
end
if u == target then
break
end
Q[u] = nil
for i,v in pairs(u:GetConnectedParts()) do
local alt = dist[u] + (v.Position-u.Position).Magnitude
if alt < dist[v] then
dist[v] = alt
prev[v] = u
end
end
end
local S = {}
local u = target
while prev[u] do
table.insert(S, 1, u)
u = prev[u]
end
table.insert(S, 1, u)
return S
end
function module:Roam(self)
spawn(function()
local TargetIndex = math.random(1, #Nodes:GetChildren())
local Target = Nodes:GetChildren()[TargetIndex]
repeat
TargetIndex = math.random(1, #Nodes:GetChildren())
until (Nodes:GetChildren()[TargetIndex].Position - self.RootPart.Position).magnitude > 8
local MoveTo = Dijkstra(Nodes, self.Start, Target)
for i,v in pairs(MoveTo) do
self.Humanoid:MoveTo(v.Position)
WaitForMoveToFinished(self, v.Position, 2)
self.Start = v
end
spawn(function() module:Roam(self) end)
end)
end
return module
Here's my module script which spawns all the NPCs:
local module = {}
local ModuleScript = require(script.Parent.ModuleScript)
local GhostTypes = require(game.ReplicatedStorage.GhostTypes)
local Types = GhostTypes.Types
local MaxNPCs = 1
local GhostIndex = 0
local NewTypes = {}
function module:InitializeAction()
for i,v in pairs(Types) do
GhostIndex = GhostIndex + 1
table.insert(NewTypes, v)
end
while (true) do
local ActiveNPCs = workspace.LocalDump:GetChildren()
local random = math.random(1, GhostIndex)
local spawnChance = NewTypes[random].Chance
local Type = NewTypes[random].Type
if (math.random(0, 100)/100 <= spawnChance) and #ActiveNPCs < MaxNPCs then
spawn(function()
local guest = ModuleScript.New(spawnChance, Type)
spawn(function() guest:Roam(guest) end)
end)
end
wait(1.5)
end
end
return module
