https://gyazo.com/bbc1696e2bda2cee8777c7428bc09930?token=67f2262697023fd2ffa8a7988e3f6a96
100 units on the field and the script activity is 33%, are there any better ways to script this?
You should try to remove the while wait() do
by an event or something.
Yeah I replaced wait() with a wait(2), that dropped the script activity down to 2%. But thats still too much for only 100 units that arent moving, shooting, or being animated
Could you paste your script? You should also use events, and also use task.wait(n) instead. If using events isn’t possible, you should increase the task.wait(n) time higher, because unless you need really fast reacting enemies, it seems good.
while wait(2) do
for i,v in pairs(game.Workspace.AISoldiers:GetChildren()) do
if v.Info.Target.Value == nil then
local Zombie
for i,zin pairs(game.Workspace.Zombies()) do -- gotta get all the enemies
if (z.HumanoidRootPart.Position - v.PrimaryPart.Position).magnitude <= v.Info.MaxRange.Value then
local Closest = 100000
local Distance = (z.HumanoidRootPart.Position - v.PrimaryPart.Position).magnitude
if Distance < Closest then
Closest = Distance
Zombie = z
end
end
v.Info.Target.Value = Zombie
end
end
end
end
changed it up a bit… now it just shoots at the closest enemy and now it dosnt search for enemies after already finding one, which will drop the script activity down to 0% but when they’re searching its still at 2%.
Try changing your script to this:
--//Variables
local AISoldiers = workspace.AISoldiers
local Zombies = workspace.Zombies
--//Functions
local function InitializeSoldier(soldier)
local targetValue = soldier:WaitForChild("Info"):WaitForChild("Target")
local function SetTarget()
if not targetValue.Value then
local nearestZombie = nil
local nearestDistance = math.huge
for i, Zombie in ipairs(Zombies:GetChildren()) do
local distance = (Zombie.HumanoidRootPart.Position - soldier.PrimaryPart.Position).Magnitude
if distance < nearestDistance then
nearestDistance = distance
nearestZombie = Zombie
end
end
targetValue.Value = nearestZombie
end
end
SetTarget()
targetValue:GetPropertyChangedSignal("Value"):Connect(function()
SetTarget()
end)
end
for i, AISoldier in ipairs(AISoldiers:GetChildren()) do
InitializeSoldier(AISoldier)
end
AISoldiers.ChildAdded:Connect(function(AISoldier)
InitializeSoldier(AISoldier)
end)
This singlehandedly dropped the script activity by like 30%, (1.6% → 1.2%) but I had to add in some of the things you missed. In this script the soldiers check the map once with an infinite range then stop.
--//Variables
local AISoldiers = workspace.AISoldiers
local Zombies = workspace.Zombies
--//Functions
local function InitializeSoldier(soldier)
local targetValue = soldier:WaitForChild("Info"):WaitForChild("Target")
local function SetTarget()
if not targetValue.Value then
local nearestZombie = nil
local nearestDistance = math.huge
for i, Zombie in ipairs(Zombies:GetChildren()) do
local distance = (Zombie.HumanoidRootPart.Position - soldier.PrimaryPart.Position).Magnitude
if distance <= soldier.Info.MaxRange.Value then -- searches for zombies in range
if distance < nearestDistance then -- closest zombie out of all the zombies in range
nearestDistance = distance
nearestZombie = Zombie
end
end
targetValue.Value = nearestZombie
end
end
end
SetTarget()
targetValue:GetPropertyChangedSignal("Value"):Connect(function()
SetTarget()
end)
end
while wait(2) do -- check frequently
for i, AISoldier in ipairs(AISoldiers:GetChildren()) do
InitializeSoldier(AISoldier)
end
end
AISoldiers.ChildAdded:Connect(function(AISoldier)
InitializeSoldier(AISoldier)
end)
That still dropped script activity from an average of 1.6% to 1.2% which is still too high the amount of units I have on the field (64 soldiers, 256 zombies)
The main source of activity is the nested loop
– Loops through all soldiers (64 loops)
– Then each soldier loops through the entire bug folder, even the bugs that are miles away (64 * 256 = 16384)
You shouldn’t run a loop to initialize the soilders multiple times. Just run that for i, loop once and it should be good.
The zombies will be out of range when it runs, then it wont run again. That’s why it has to keep on checking through a loop.
Then add the loop inside the SetTarget function while checking the value. The way you did it is connecting hundreds of functions that you aren’t disconnecting.
Your script activity is happening cause of loops within loops, stop looping through all of them and just save an array of the zombie models and just loop through those each time.
You can also just create a sphere part representing the range and use zone plus so theres no while wait() do but that might be tedious.
But how’d I compare the distance of the zombies in that array to the soldiers?
You’d make a map relation between them all if you are looking to optimize time complexity at the cost of space complexity.