Hi, its my first time making an enemy AI and i’ve got a problem that i’ll end up running into in the future, i have this script that uses RunService.Stepped to find the closest player, it works well but there are going to be a lot of enemies and it eventually builds up and lags the game, so i was wondering if they is a different option or a solution i can do.
here is my code
–Calling Module
local EnemyConfig = require(script.Parent.EnemyConfig)
–Services
local Players = game:GetService(“Players”)
local RunService = game:GetService(“RunService”)
–Variables
local Enemy = script.Parent
local EnemyHumanoid = Enemy.Humanoid
local EnemyHumanoidRootPart = Enemy.HumanoidRootPart
–ModuleVariables
local Health = EnemyConfig.Health
local WalkSpeed = EnemyConfig.WalkSpeed
local JumpPower = EnemyConfig.JumpPower
local Damage = EnemyConfig.Damage
local FollowDistance = EnemyConfig.FollowDistance
local RespawnTime = EnemyConfig.RespawnTime
local Range = EnemyConfig.Range
local Gold = EnemyConfig.Rewards.Gold
local EXP = EnemyConfig.Rewards.EXP
–AssigningStats
EnemyHumanoid.MaxHealth = Health
EnemyHumanoid.Health = Health
EnemyHumanoid.WalkSpeed = WalkSpeed
EnemyHumanoid.JumpPower = JumpPower
local function MoveEnemy()
local Target = nil
local PlayersInGame = Players:GetPlayers()
for _,Player in pairs(PlayersInGame) do
local Character = Player.Character
if Character then
local CharacterHumanoidRootPart = Character:FindFirstChild("HumanoidRootPart")
if CharacterHumanoidRootPart and (EnemyHumanoidRootPart.Position - CharacterHumanoidRootPart.Position).Magnitude < Range then
if Target then
if (EnemyHumanoidRootPart.Position - Target.Position).Magnitude > (EnemyHumanoidRootPart.Position - CharacterHumanoidRootPart.Position).Magnitude then
Target = CharacterHumanoidRootPart
end
else
Target = CharacterHumanoidRootPart
end
end
end
end
if Target then
EnemyHumanoid:MoveTo(Target.Position)
end
print(Target)
you could use a combination of render stepped for detecting players and then a while loop for movement
for ex. on render step check for players, if you find a player, disconnect the renderstep and start a walking while loop that will eventually reconnect the renderstep function
Instead of having a script for each enemy, you could create one script that has a table of all the enemies, then use one connection that loops through each enemy and moves it.
Edit: The performance issue is not from RunService.Stepped, but from the multiple connections to it.
yeah that would probably work but i’m not the greatest at scripting and it sounds a bit complex for me, how would i signal to a certain enemy? i’ll give it a shot since it sounds like it would run the best out of all the other options i’ve been given also there will be multiple enemies with the same name, that shouldn’t cause a problem since its in a table right?
If you use a for loop on the table, you will be given an index, and a value. The value is the enemy.
local EnemyTable = {}
table.insert(EnemyTable, enemy)
for index, value in pairs(EnemyTable) do
-- index is the current iteration
-- value is the current enemy
end
You can find a specific enemy in the table using table.find.