I’m making a wave based game and I’m using modules for the enemy AI. But for some reason the AI acts differently than the script in the enemy itself. (I don’t wanna put scripts in the enemies so the game doesn’t lag)
Here’s what’s happening:
Here’s the code: (there’s no difference main code itself between the 2)
local module = {}
module.Activate = function(enemy)
local players = game:GetService("Players")
local myHuman = enemy:WaitForChild("Humanoid")
local myRoot = enemy:WaitForChild("HumanoidRootPart")
local head = enemy:WaitForChild("Head")
local lowerTorso = enemy:WaitForChild("LowerTorso")
local damageMod = require(game.ReplicatedStorage.Modules.DamageMod)
local function attack(target)
if (myRoot.Position - target.Position).magnitude < 5 then
if target.Parent ~= nil then
damageMod.Damage(target.Parent.Humanoid, 1)
end
wait(0.4)
end
end
local function checkSight(target)
local ray = Ray.new(myRoot.Position, (target.Position - myRoot.Position).Unit * 40)
local hit,position = workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent})
if hit then
if hit:IsDescendantOf(target.Parent) and math.abs(hit.Position.Y - myRoot.Position.Y) < 3 then
return true
end
end
return false
end
local function findPath(target)
print("Finding path to target")
local path = game:GetService("PathfindingService"):CreatePath()
path:ComputeAsync(myRoot.Position, target.Position)
local waypoints = path:GetWaypoints()
if path.Status == Enum.PathStatus.Success then
print("Path found, moving to waypoints")
for _, waypoint in ipairs(waypoints) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
myHuman.Jump = true
end
myHuman:MoveTo(waypoint.Position)
local timeOut = myHuman.MoveToFinished:Wait(0.1)
if not timeOut then
print("MoveTo timeout, recalculating path")
myHuman.Jump = true
findPath(target)
break
end
if checkSight(target) then
print("Target in sight, attacking")
repeat
myHuman:MoveTo(target.Position)
attack(target)
wait()
if target == nil or target.Parent == nil then
break
end
until checkSight(target) == false or myHuman.Health < 1 or target.Parent.Humanoid.Health < 1
break
end
if (myRoot.Position - waypoints[1].Position).magnitude > 20 then
print("Waypoint too far, recalculating path")
findPath(target)
break
end
end
else
print("Pathfinding failed, retrying")
wait(1)
end
end
local function findTarget()
local dist = math.huge
local target = nil
local potentialTargets = {}
local seeTargets = {}
for i,v in ipairs(workspace:GetChildren()) do
local human = v:FindFirstChild("Humanoid")
local torso = v:FindFirstChild("Torso") or v:FindFirstChild("HumanoidRootPart")
if human and torso and v.Name ~= script.Parent.Name and players:GetPlayerFromCharacter(torso.Parent) then
if (myRoot.Position - torso.Position).magnitude < dist and human.Health > 0 then
table.insert(potentialTargets,torso)
end
end
end
if #potentialTargets > 0 then
for i,v in ipairs(potentialTargets) do
if checkSight(v) then
table.insert(seeTargets, v)
elseif #seeTargets == 0 and (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
if #seeTargets > 0 then
dist = 200
for i,v in ipairs(seeTargets) do
if (myRoot.Position - v.Position).magnitude < dist then
target = v
dist = (myRoot.Position - v.Position).magnitude
end
end
end
return target
end
local function main()
local target = findTarget()
if target then
myHuman.WalkSpeed = 16
findPath(target)
end
end
local function die()
head.Parent:Destroy()
end
myHuman.Died:Connect(die)
lowerTorso.Touched:Connect(function(obj)
if not obj.Parent:FindFirstChild("Humanoid") and not obj.Parent:GetAttribute("Enemy") and not obj.Parent.Parent:GetAttribute("Enemy") and obj.Name ~= "Hitbox" and not players:GetPlayerFromCharacter(obj.Parent) and not players:GetPlayerFromCharacter(obj.Parent.Parent) then
myHuman.Jump = true
end
end)
while wait(0.1) do
if myHuman.Health < 1 then
break
end
main()
end
end
return module