Hi, I’ve been looking to optimise the scripts in a game I’m working on and I read somewhere that all scripts should be less than 3% Activity in the script performance tool in studio. The only script over 3% is this Bot Ai script which is working perfectly except for some reason seems to be causing a TON of lag and constantly in the 38-55% Activity range.
I presume it has something to do with the while wait() do
on line 136, however I don’t know how else to have it so it will constantly check but without taking a huge impact on performance?
This is a server sided script btw.
local SearchDistance = 100000000
local WanderX, WanderZ = 30, 30
function getHumanoid(model)
for _, v in pairs(model:GetChildren())do
if v:IsA'Humanoid' then
return v
end
end
end
local Bot = script.Parent
local human = Bot.Zombie
local hroot = Bot.HumanoidRootPart
local zspeed = hroot.Velocity.magnitude
local head = Bot.Head
local vars = script.vars
local pfs = game:GetService("PathfindingService")
local players = game:GetService('Players')
local Monster = script.Parent
Monster.HumanoidRootPart:SetNetworkOwner(nil)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
local path
local waypoint
local chaseName = nil
function GetTorso(part)
local chars = game.Workspace:GetDescendants()
local chaseRoot = nil
local chaseTorso = nil
local chasePlr = nil
local chaseHuman = nil
local mag = SearchDistance
for i = 1, #chars do
chasePlr = chars[i]
if chasePlr:IsA'Model' and not chasePlr:FindFirstChild("Enemy") and not chasePlr:FindFirstChild("Helper") then
chaseHuman = getHumanoid(chasePlr)
chaseRoot = chasePlr:FindFirstChild'HumanoidRootPart'
if chaseRoot ~= nil and chaseHuman ~= nil and chaseHuman.Health > 0 and not chaseHuman:FindFirstChild("Enemy") and not chasePlr:FindFirstChild("Helper") then
if (chaseRoot.Position - part).magnitude < mag then
chaseName = chasePlr.Name
chaseTorso = chaseRoot
mag = (chaseRoot.Position - part).magnitude
end
end
end
end
return chaseTorso
end
function GetPlayersBodyParts(t)
local torso = t
if torso then
local figure = torso.Parent
for _, v in pairs(figure:GetChildren())do
if v:IsA'Part' then
return v.Name
end
end
else
return "HumanoidRootPart"
end
end
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- wandering
spawn(function()
while vars.Wandering.Value == false and human.Health > 0 do
vars.Chasing.Value = false
vars.Wandering.Value = true
local desgx, desgz = hroot.Position.x+math.random(-WanderX,WanderX), hroot.Position.z+math.random(-WanderZ,WanderZ)
local function checkw(t)
local ci = 3
if ci > #t then
ci = 3
end
if t[ci] == nil and ci < #t then
repeat ci = ci + 1 wait() until t[ci] ~= nil
return Vector3.new(1,0,0) + t[ci]
else
ci = 3
return t[ci]
end
end
path = pfs:FindPathAsync(hroot.Position, Vector3.new(desgx, 0, desgz))
waypoint = path:GetWaypoints()
local connection;
local direct = Vector3.FromNormalId(Enum.NormalId.Front)
local ncf = hroot.CFrame * CFrame.new(direct)
direct = ncf.p.unit
local rootr = Ray.new(hroot.Position, direct)
local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot)
if path and waypoint or checkw(waypoint) then
if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
human:MoveTo( checkw(waypoint).Position )
human.Jump = false
end
if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Jump then
connection = human.Changed:connect(function()
human.Jump = true
end)
human:MoveTo( waypoint[4].Position )
else
human.Jump = false
end
if connection then
connection:Disconnect()
end
else
for i = 3, #waypoint do
human:MoveTo( waypoint[i].Position )
end
end
wait(math.random(4,6))
vars.Wandering.Value = false
end
end)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
while wait() do
local nrstt = GetTorso(hroot.Position)
if nrstt ~= nil and human.Health > 0 then -- if player detected
vars.Wandering.Value = false
vars.Chasing.Value = true
local function checkw(t)
local ci = 3
if ci > #t then
ci = 3
end
if t[ci] == nil and ci < #t then
repeat ci = ci + 1 wait() until t[ci] ~= nil
return Vector3.new(1,0,0) + t[ci]
else
ci = 3
return t[ci]
end
end
path = pfs:FindPathAsync(hroot.Position, nrstt.Position)
waypoint = path:GetWaypoints()
local connection;
local direct = Vector3.FromNormalId(Enum.NormalId.Front)
local ncf = hroot.CFrame * CFrame.new(direct)
direct = ncf.p.unit
local rootr = Ray.new(hroot.Position, direct)
local phit, ppos = game.Workspace:FindPartOnRay(rootr, hroot)
if path and waypoint or checkw(waypoint) then
if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
human:MoveTo( checkw(waypoint).Position )
human.Jump = false
end
if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Jump then
connection = human.Changed:connect(function()
human.Jump = true
end)
human:MoveTo( waypoint[4].Position )
else
human.Jump = false
end
if connection then
connection:Disconnect()
end
else
for i = 3, #waypoint do
human:MoveTo( waypoint[i].Position )
end
end
path = nil
waypoint = nil
elseif nrstt == nil then
vars.Wandering.Value = true
vars.Chasing.Value = false
CchaseName = nil
path = nil
waypoint = nil
human.MoveToFinished:Wait()
end
end
Any suggestions would be greatly appreciated,
Thanks, Aidan