So, I use many different enemies in my game, each one with its own AI script.
The issue is, the game tends to crash for the players!
And it’s not consistent, some just lag, and some others crash instantly (and they’re forced to stop task)
I don’t know if the amount of AI scripts is what causes this (From what I’ve seen in Script Performance, it can reach up to 30% with around 10 to 15 enemies, and the game is supposed to have up to 30 in some scenarios.)
I’ve tried to investigate making a universal AI for the enemies, but I have no idea how to get started (Since every enemy has a different walk speed, and they also deal different damage.)
Here’s an example of a script that an enemy uses, with some unnecessary parts removed:
sp = script.Parent
AttackSpeed = 0.75
TimeToJump = math.random(1, 10)
variance = 2
local Damage = 10
attackrange = 3
sightrange = 500
SpeedDebounce = false
function raycast(spos,vec,currentdist)
local hit2,pos2=game.Workspace:FindPartOnRay(Ray.new(spos+(vec*.01),vec*currentdist),script.Parent)
if hit2~=nil and pos2 then
if hit2.Parent==script.Parent and hit2.Transparency>=.8 or hit2.Name=="Handle" or string.sub(hit2.Name,1,6)=="Effect" or hit2.Parent:IsA("Hat") or hit2.Parent:IsA("Tool") or (not hit2.Parent:FindFirstChild("Humanoid") and hit2.CanCollide==false) then
local currentdist=currentdist-(pos2-spos).magnitude
wait()
return raycast(pos2,vec,currentdist)
end
end
return hit2,pos2
end
function waitForChild(parent,childName)
local child=parent:findFirstChild(childName)
if child then return child end
while true do
child=parent.ChildAdded:wait()
if child.Name==childName then return child end
end
end
-- ANIMATION
-- declarations
local Torso=waitForChild(sp,"Torso")
local Head=waitForChild(sp,"Head")
local RightShoulder=waitForChild(Torso,"Right Shoulder")
local LeftShoulder=waitForChild(Torso,"Left Shoulder")
local RightHip=waitForChild(Torso,"Right Hip")
local LeftHip=waitForChild(Torso,"Left Hip")
local Neck=waitForChild(Torso,"Neck")
local Humanoid=waitForChild(sp,"Humanoid")
local pose="Standing"
local hitsound=waitForChild(Torso,"HitSound")
local Anim = Humanoid:LoadAnimation(sp.AttackAnim)
function attack(AttackSpeed,attackpos)
if AttackSpeed then
local hit,pos=raycast(Torso.Position,(attackpos-Torso.Position).unit,attackrange)
if hit and hit.Parent~=nil then
local h=hit.Parent:FindFirstChild("Humanoid")
if h and hit.Parent.Parent.Name ~= "Enemies" then
local creator=sp:FindFirstChild("creator")
if creator then
if creator.Value~=nil then
if creator.Value~=game.Players:GetPlayerFromCharacter(h.Parent) then
for i,oldtag in ipairs(h:GetChildren()) do
if oldtag.Name=="creator" then
oldtag:remove()
end
end
creator:clone().Parent=h
else
return
end
end
end
if Anim then Anim:Play(nil, nil, 2) end
local Character = h.Parent
if Character:FindFirstChild("IsATower") then
h:TakeDamage(math.floor(Damage))
end
hitsound:Play()
wait(AttackSpeed)
end
end
end
end
function populatehumanoids(model)
if model.ClassName=="Humanoid" then
if model.Parent.Name ~= sp.Name and model.Parent.Parent.Name ~= "Enemies" then
table.insert(humanoids,model)
end
end
for i2, model2 in ipairs(model:GetChildren()) do
populatehumanoids(model2)
end
end
while sp and Humanoid and Humanoid.Health > 0 do
local TimeLeft = game.Workspace.Values.TimeLeft
wait(0.5)
humanoids={}
populatehumanoids(game.Workspace)
closesttarget=nil
closestdist=sightrange
local creator=sp:FindFirstChild("creator")
for i,h in ipairs(humanoids) do
if h and h.Parent~=nil then
if h.Health>0 and h.Parent ~= sp then
local plr=game.Players:GetPlayerFromCharacter(h.Parent)
if creator==nil or plr==nil or creator.Value~=plr then
local t=h.Parent:FindFirstChild("HumanoidRootPart")
local towercheck = h.Parent:FindFirstChild("IsATower")
if t ~= nil and towercheck ~= nil then
local dist=(t.Position-Torso.Position).magnitude
if dist<closestdist then
closestdist=dist
closesttarget=t
end
end
end
end
end
end
if closesttarget~=nil then
if TimeLeft.Value > 0 then
if SpeedDebounce == true then
SpeedDebounce = false
script.Parent.Humanoid.WalkSpeed = script.Parent.Humanoid.WalkSpeed * 2
end
-- Move and attack towards the nearest player
elseif TimeLeft.Value <= 0 then
if SpeedDebounce == false then
SpeedDebounce = true
script.Parent.Humanoid.WalkSpeed = script.Parent.Humanoid.WalkSpeed / 2
end
-- Move towards the main objective and attack any player that gets in range
end
else
if TimeLeft.Value <= 0 then
if SpeedDebounce == false then
SpeedDebounce = true
script.Parent.Humanoid.WalkSpeed = script.Parent.Humanoid.WalkSpeed / 2
end
-- Move towards the main objective and attack any player that gets in range
end
end
if TimeToJump == 2 and Humanoid.MoveDirection.magnitude <= 0 then
Humanoid.Jump = true
end
TimeToJump = math.random(1, 10)
end