Heya Everyone!!
I’m trying to find a way to stop a NPC from moving once in their attacking range and move once away from their attacking range. I tried finding posts but couldn’t find one aside from this one and tried checking the magnitude if its less or greater than the attack range to stop moving but didn’t work.
Honestly, I should’ve known how to do this already but this is kinda embarrassing?
--[[DEVELOPER NOTES]]--
--//Rough module script, I know.
--//This is fine but it can definitely be improved on some parts.
--[[SERVICES]]--
local ServerStorage = game:GetService("ServerStorage")
local PathfindingService = game:GetService("PathfindingService")
local Debris = game:GetService("Debris")
--[[FOLDERS]]--
local Entities_Folder = ServerStorage:WaitForChild("ENTITIES")
local Allies_Foldder = Entities_Folder:FindFirstChild("ALLIES")
local Enemies_Folder = Entities_Folder:FindFirstChild("ENEMIES")
--[[MODULES]]--
local BASE_ENTITY_MODULE = {}
BASE_ENTITY_MODULE.__index = BASE_ENTITY_MODULE
function BASE_ENTITY_MODULE.CreateEntity(EntityName, EntityTeam)
--//Sorting out what team the entity is so we can find their folders.
local SearchFolder = if EntityTeam == "Allies" then Allies_Foldder
elseif EntityTeam == "Enemies" then Enemies_Folder
else nil
--//Checking to see if the entity DOES exist.
local UnitModel = nil
for _, FindUnit in pairs(SearchFolder:GetChildren()) do
if FindUnit:IsA("Model") and FindUnit.Name == EntityName then
UnitModel = FindUnit:Clone()
elseif FindUnit:IsA("Model") and FindUnit.Name ~= EntityName then
warn(EntityName.." doesn't exist!")
return
end
end
--//Creating the entity.
local self = setmetatable({}, BASE_ENTITY_MODULE)
self.Unit = UnitModel
self.UnitHumanoid = self.Unit:FindFirstChildWhichIsA("Humanoid")
self.UnitTeam = self.Unit:AddTag(EntityTeam)
self.Unit.Parent = workspace
--//Entity Settings
self.EntitySettings = require(self.Unit.ENTITY_SETTINGS)
self.EntityDamage = self.EntitySettings.ENTITY_DAMAGE
self.EntityAttackRate = self.EntitySettings.ENTITY_ATTACK_RATE
self.EntityAttackRange = self.EntitySettings.ENTITY_ATTACK_RANGE --Using this in order to detect if the NPC/entity is in attacking range.
self.EntityResistance = self.EntitySettings.ENTITY_RESISTANCE
task.spawn(function()
game:GetService("RunService").Heartbeat:Connect(function()
local Target = self:FindNearestTarget()
if Target then
self:ChaseTarget(Target)
else
self.UnitHumanoid:MoveTo(self.Unit.PrimaryPart.Position)
end
end)
end)
return self
end
function BASE_ENTITY_MODULE:FindNearestTarget()
local Targets = {}
local Nearest = math.huge
local Target = nil
for _, PotentialTargets in pairs(workspace:GetChildren()) do
if PotentialTargets:IsA("Model") then
local TargetHumanoid = PotentialTargets:FindFirstChildWhichIsA("Humanoid")
if TargetHumanoid.Health <= 0 then --//Dead, obviously.
return
end
local Distance = (PotentialTargets.PrimaryPart.Position - self.Unit.PrimaryPart.Position).Magnitude
if Distance <= math.huge then
if (PotentialTargets:HasTag("Enemies") and self.Unit:HasTag("Allies")) or
(PotentialTargets:HasTag("Allies") and self.Unit:HasTag("Enemies")) then
table.insert(Targets,{
Magnitude = Distance,
FoundTarget = PotentialTargets
})
end
end
end
end
for _, Entry in pairs(Targets) do
if Entry.Magnitude <= Nearest then
Nearest = Entry.Magntidue
Target = Entry.FoundTarget
end
end
return Target
end
function BASE_ENTITY_MODULE:ChaseTarget(Target)
local NewPath = PathfindingService:CreatePath()
NewPath:ComputeAsync(Target.PrimaryPart.Position, self.Unit.PrimaryPart.Position)
if NewPath.Status == Enum.PathStatus.Success then
local Waypoints = NewPath:GetWaypoints()
for _, Waypoint in pairs(Waypoints) do
self.UnitHumanoid:MoveTo(Waypoint.Position)
local Timeout = self.UnitHumanoid.MoveToFinished:Wait(2)
if not Timeout then
self:ChaseTarget(Target)
end
end
end
end
return BASE_ENTITY_MODULE