So, i have this script, that allows an AI that will attack any nearby players/characters with weapons. But there’s a few issues, the core of this script is pretty old, and the NPC can be a bit laggy / jittery, and the code is a bit on the messy side. There are also times where the NPC would just teleport due to lag. How could i improve this?
Humanoid = script.Parent:WaitForChild("Humanoid")
Config = script.Parent:WaitForChild("Config")
AttackPlayersOnly = Config:WaitForChild("AttackPlayersOnly")
AttackDist = Config:WaitForChild("AttackDistance")
UseWeaponDist = Config:WaitForChild("UseWeaponDistance")
HurtAttackDist = Config:WaitForChild("HurtAttackDistance")
OrigWalkSpeed = Humanoid.WalkSpeed
WalkAnim = Humanoid:LoadAnimation(Config:WaitForChild("WalkAnim"))
IdleAnim = Humanoid:LoadAnimation(Config:WaitForChild("IdleAnim"))
function Attack()
local Item = script.Parent:FindFirstChildOfClass("Tool")
if Item then
local Activate = Item:FindFirstChild("ActivateWeapon")
if Activate and Activate.ClassName == "BoolValue" then -- The AI has a usable weapon
Activate.Value = true
end
end
end
function findNearestTorso(pos)
local list = game.Workspace:children()
local torso = nil
local temp = nil
local human = nil
local temp2 = nil
for x = 1, #list do
temp2 = list[x]
if (temp2.className == "Model") and (temp2 ~= script.Parent) then
temp = temp2:findFirstChild("Torso")
human = temp2:findFirstChild("Humanoid")
local function Follow()
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) then
if (temp.Position - pos).magnitude < AttackDist.Value then
torso = temp
--AttackDist.Value = (temp.Position - pos).magnitude
end
if (temp.Position - pos).magnitude < UseWeaponDist.Value then
Attack()
end
end
end
if AttackPlayersOnly.Value == true and human then
local PlayerCheck = game:GetService("Players"):FindFirstChild(human.Parent.Name)
if PlayerCheck then
Follow()
end
else
Follow()
end
end
end
return torso
end
--wait(math.random(0,5)/10)
while true do
wait(0.3)
local target = findNearestTorso(script.Parent.Torso.Position)
if target ~= nil then
Humanoid.WalkSpeed = OrigWalkSpeed
Humanoid:MoveTo(target.Position, target) -- My time has come
if WalkAnim.IsPlaying == false or IdleAnim.IsPlaying == true then
IdleAnim:Stop()
WalkAnim:Play()
end
else
-- Target has walked away, i guess we just stand here now.
if WalkAnim.IsPlaying == true or IdleAnim.IsPlaying == false then
WalkAnim:Stop()
IdleAnim:Play()
end
Humanoid.WalkSpeed = 0
end
end
OldHealth = Humanoid.Health
Humanoid.HealthChanged:Connect(function()
if Humanoid.Health < OldHealth and Humanoid.Health > 0 then -- Humanoid has been damaged
local OrigDist = AttackDist.Value
AttackDist.Value = HurtAttackDist.Value
wait(15)
AttackDist.Value = OrigDist
end
OldHealth = Humanoid.Health
end)