Advertisement
Johnapolitan

Quick Enemy AI Example

Jun 24th, 2022
1,008
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.21 KB | None
  1. local Enemy = {}
  2. Enemy.__index = Enemy
  3. local Tag = "Enemy"
  4.  
  5. --//Services
  6. local Players = game:GetService("Players")
  7. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  8. local CollectionService = game:GetService("CollectionService")
  9.  
  10. --//Paths
  11. local Modules = ReplicatedStorage:WaitForChild("Modules")
  12. local Util = Modules:WaitForChild("Util")
  13. local EnemySpawn = workspace:WaitForChild("CombatTesting"):WaitForChild("EnemySpawn")
  14.  
  15. --//Modules
  16. local Janitor = require(Util:WaitForChild("Janitor"))
  17. local HumanoidList = require(script.Parent.Parent.HumanoidList)
  18.  
  19. --//CONSTANTS
  20. local AGGRORANGE = 50 --How many studs away player needs to be for enemy to attack
  21. local ATTACK_DELAY = 2
  22. local KILL_RANGE = 2.5
  23. local ATTACK_DAMAGE = 20
  24. --//Private Vars
  25. local States = {
  26.     "Searching";
  27.     "Attack";
  28. }
  29. local AttackDebounce = false
  30.  
  31. local function GetDistance(p1, p2)
  32.     return (p1.Position - p2.Position).magnitude
  33. end
  34.  
  35. local function GetClosestVisibleTarget(enemy, targets, blacklist)
  36.     --NOTE WE MAY NOT NEED BLACKLIST SO STOP COLLECTING IT
  37.     local distances = {}
  38.     for _, char in ipairs(targets) do
  39.         if CollectionService:HasTag(char, Tag) then continue end
  40.         distances[char] = GetDistance(enemy.PrimaryPart, char.PrimaryPart)
  41.     end
  42.     local low = math.huge
  43.     local index
  44.     for i, v in pairs(distances) do
  45.         if v < low then
  46.             low = v
  47.             index = i
  48.         end
  49.     end
  50.     return index
  51. end
  52.  
  53. --//Enemy Functions/Methods
  54. function Enemy.new(instance)
  55.     local self = setmetatable({}, Enemy)
  56.     self._janitor = Janitor.new()
  57.     self.Instance = instance
  58.     self.Humanoid = instance.Humanoid
  59.     return self
  60. end
  61.  
  62. function Enemy:Attack()
  63.     if self.Instance == nil then warn("An instance is required in order for the enemy to attack.") return end
  64.     if self.Target == nil then warn("A target is required in order for the enemy to attack.") end
  65.     self.State = States[2]
  66.  
  67.  
  68.     local function takeDMG()
  69.         while true do
  70.             self.Humanoid:MoveTo(self.Target.HumanoidRootPart.Position)
  71.             self.Humanoid.MoveToFinished:Wait()
  72.             local plr = Players:GetPlayerFromCharacter(self.Target)
  73.             if not plr then return end
  74.             local distance = (self.Instance.HumanoidRootPart.Position - self.Target.HumanoidRootPart.Position).magnitude
  75.             if distance <= KILL_RANGE then
  76.                 local playerDefense = plr:GetAttribute("Defense")
  77.                 if playerDefense then
  78.                     local hp = self.Target.Humanoid.Health
  79.                     local amt = (playerDefense * hp)
  80.  
  81.                     self.Target.Humanoid:TakeDamage(amt)
  82.                     AttackDebounce = true
  83.                 else
  84.                     self.Target.Humanoid:TakeDamage(20)
  85.                     AttackDebounce = true
  86.                 end
  87.                 task.wait(ATTACK_DELAY)
  88.             end
  89.         end
  90.     end
  91.     task.spawn(takeDMG)
  92.     local distance = (self.Instance.HumanoidRootPart.Position - self.Target.HumanoidRootPart.Position).magnitude
  93.     if distance > AGGRORANGE then
  94.         self:PrimeForAttack()
  95.     end
  96. end
  97.  
  98. function Enemy:PrimeForAttack()
  99.     local keepGoing = true
  100.     if self.Instance then
  101.         while keepGoing do
  102.             -- Get list of all nearby enemies and non-enemy humanoids
  103.             -- Enemy list is used to ignore other enemies during later detection
  104.             local humanoids = HumanoidList:GetCurrent()
  105.             local friendlies = {}
  106.             local characters = {}
  107.             for _, object in pairs(humanoids) do
  108.                 if object and object.Parent and object.Parent:FindFirstChild("HumanoidRootPart") and object.Health > 0 and object.WalkSpeed > 0 then
  109.                     local torso = object.Parent:FindFirstChild("HumanoidRootPart")
  110.                     if torso then
  111.                         local plr = Players:GetPlayerFromCharacter(object.Parent)
  112.                         if plr then
  113.                             local distance = (self.Instance.HumanoidRootPart.Position - torso.Position).magnitude
  114.                             if distance <= AGGRORANGE then
  115.                                 if CollectionService:HasTag(object, Tag) then
  116.                                     table.insert(friendlies, object.Parent)
  117.                                 else
  118.                                     table.insert(characters, object.Parent)
  119.                                 end
  120.                             end
  121.                         end
  122.                     end
  123.                 end
  124.             end
  125.  
  126.             local target = GetClosestVisibleTarget(self.Instance, characters, friendlies)
  127.             if target then
  128.                 keepGoing = false
  129.                 self.Target = target
  130.                 self:Attack()
  131.             else
  132.                 self.Humanoid:MoveTo(EnemySpawn.Position)
  133.             end
  134.             task.wait(3)
  135.         end
  136.     end
  137. end
  138.  
  139. function Enemy:Init()
  140.     print("Enemy was initialized")
  141.     self.State = States[1]
  142.     self:PrimeForAttack()
  143. end
  144.  
  145. return Enemy
Advertisement
RAW Paste Data Copied
Advertisement