So I have a AI script that works fine, but it lags when there are a lot of them, I tried to implement Collection service, but it doesn’t seem to affect more than one of the AI’s.
Here is the code on a script in ServerscriptService
local CollectionService = game:GetService("CollectionService")
wait(5)
function walkRandomly(myRoot, myHuman, walkanim, IdleAnim)
local xRand = math.random(-10,10)
local zRand = math.random(-10,10)
local goal = myRoot.Position + Vector3.new(xRand,0,zRand)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position, goal)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
--walkanim:Play()
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(1)
if not timeOut then
myHuman.Jump = true
walkRandomly(myRoot, myHuman, walkanim, IdleAnim)
end
if timeOut then
local lastwaypoint = table.find(waypoints,waypoint)
if lastwaypoint == #waypoints then
--walkanim:Stop()
--IdleAnim:Play()
end
end
end
else
wait(1)
walkRandomly(myRoot, myHuman, walkanim, IdleAnim)
end
end
function findPath(target, myRoot, myHuman, walkanim, IdleAnim, damage, db, attackanim)
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position,target.Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
if db == true then
myHuman.WalkSpeed = 18
end
for _, waypoint in ipairs(waypoints) do
--walkanim:Play()
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(1)
if not timeOut then
myHuman.Jump = true
findPath(target, myRoot, myHuman, walkanim, IdleAnim, damage, db, attackanim)
--walkanim:Stop()
--IdleAnim:Play()
break
end
if timeOut then
local lastwaypoint = table.find(waypoints,waypoint)
if lastwaypoint == #waypoints then
--walkanim:Stop()
--IdleAnim:Play()
end
end
repeat
myHuman:MoveTo(target.Position)
attack(target, myRoot, damage, db, attackanim)
wait(0.1)
if target == nil then
--walkanim:Stop()
--IdleAnim:Play()
break
elseif target.Parent == nil then
--walkanim:Stop()
--IdleAnim:Play()
break
end
until myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
findPath(target)
--walkanim:Stop()
--IdleAnim:Play()
break
end
end
else
walkRandomly(myRoot, myHuman, walkanim, IdleAnim)
end
end
function findTarget(myRoot)
local dist = 400
local target = nil
local potentialTargets = {}
for i,v in ipairs(game.Players:GetChildren()) do
local human = v.Character:FindFirstChild("Humanoid")
local torso = v.Character:FindFirstChild("HumanoidRootPart")
if human and torso and v.Name ~= myRoot.Parent.Name then
if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 then
table.insert(potentialTargets,torso)
end
end
end
for i,v in ipairs(potentialTargets) do
if (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
return target
end
function attack(target, myRoot, damage, db, attackanim)
if (myRoot.Position - target.Position).magnitude < 6 then
if target.Parent ~= nil and db == true then
db = false
attackanim:Play()
local oldspeed = myRoot.Parent.Zombie.WalkSpeed
myRoot.Parent.Zombie.WalkSpeed = 0
wait(0.2)
target.parent.Humanoid:TakeDamage(damage)
wait(1.75)
db = true
myRoot.Parent.Zombie.WalkSpeed = oldspeed
end
wait(0.4)
end
end
function main(Zombie)
local myHuman = Zombie:WaitForChild("Zombie")
local myRoot = Zombie:WaitForChild("HumanoidRootPart")
local head = Zombie:WaitForChild("Head")
local lowerTorso = Zombie:WaitForChild("LowerTorso")
local damage = Zombie:WaitForChild("Damage").Value
local db = true
local walkanim = Zombie.Zombie:LoadAnimation(Zombie.Walk)
local IdleAnim = Zombie.Zombie:LoadAnimation(Zombie.Idle)
local attackanim = Zombie.Zombie:LoadAnimation(Zombie.Attack)
local target = findTarget(myRoot)
if target then
findPath(target, myRoot, myHuman, walkanim, IdleAnim, damage, db, attackanim)
else
wait(math.random(1,4))
walkRandomly(myRoot, myHuman, walkanim, IdleAnim)
end
end
game:GetService("RunService").Heartbeat:Connect(function()
for _,Zombie in pairs(CollectionService:GetTagged("Zombie")) do
main(Zombie)
end
end)
I’ve searched around and found that global values break the script, so i’ve combed through the script about 4 times, but haven’t found any global values