Hello. Ive done some researching on this problem, but I have found nothing.
Basically, I have made an AI that finds and kills players and other npcs.
However, after a kill, the AI will stand still, and will keep standing still until the player or npc despawns.
After the player/npc despawns, the AI goes to killing people again.
Anyway to fix this?
My code: (While not recommended to look at it as it causes loss of braincells, you can tell I am in a struggle to try and make this work)
local replicatedStorage = game:GetService("ReplicatedStorage")
local pathModule = require(script.SimplePath)
local maxDistance = math.huge
local players = game:GetService("Players")
local parent = script.Parent
parent.PrimaryPart:SetNetworkOwner(nil)
local aware = false
local human = script.Parent:WaitForChild("Humanoid")
local DAMAGE = 5
local AMMO = 20
local MAX_AMMO = 20
local moving_backwards = false
local cooldown = false
local is_reloading = false
local screenShakeEvent = replicatedStorage:WaitForChild("events"):WaitForChild("remotes"):WaitForChild("shake_remote")
task.wait(1)
local ignore = {}
function findTarget()
local closest_player, closest_distance = nil, maxDistance
for i, player in pairs(workspace:GetDescendants()) do
if player:IsA("Model") and player:FindFirstChildOfClass("Humanoid") and player ~= parent and not table.find(ignore, player) then
local faction = player:FindFirstChild("faction")
if faction.Value ~= parent.faction.Value then
local char = player
local distance = (parent.PrimaryPart.Position - char.HumanoidRootPart.Position).Magnitude
local targethuman:Humanoid = char:FindFirstChildOfClass("Humanoid")
if targethuman.Health <= 0 then
closest_player = nil
closest_distance = maxDistance
return
end
if targethuman.Health > 0 then
if distance < closest_distance then
closest_player = char
closest_distance = distance
end
end
end
end
end
return closest_player
end
function CREATE_TRAIL_(ORIGIN, POINT)
local REPLICATED_STORAGE = game:GetService("ReplicatedStorage")
local MISCS = REPLICATED_STORAGE.miscs
local BULLET = MISCS.Bullet:Clone()
local TRAIL = MISCS.Trail:Clone()
TRAIL.Attachment0.WorldPosition = ORIGIN
TRAIL.Attachment0.WorldCFrame = CFrame.lookAt(TRAIL.Attachment0.WorldPosition, POINT)
TRAIL.Attachment1.WorldPosition = POINT
TRAIL.Attachment1.WorldCFrame = CFrame.lookAt(TRAIL.Attachment1.WorldPosition, POINT)
BULLET.Position = ORIGIN
BULLET.CFrame = CFrame.lookAt(ORIGIN, POINT)
TRAIL.Parent = workspace
BULLET.Parent = workspace
coroutine.wrap(function()
local LOOP
local RUN_SERVICE = game:GetService("RunService")
LOOP = RUN_SERVICE.Heartbeat:Connect(function(DT)
BULLET.CFrame *= CFrame.new(0, 0, -10 * (DT * 60))
if (BULLET.Position - POINT).Magnitude < 4 or (ORIGIN - BULLET.Position).Magnitude > 1000 then
BULLET:Destroy()
LOOP:Disconnect()
end
end)
end)()
local TWEEN_SERVICE = game:GetService("TweenService")
local GOAL = {}
GOAL = {Width0 = 0}
local TWEEN = TWEEN_SERVICE:Create(TRAIL.Beam, TweenInfo.new(1), GOAL)
TWEEN:Play()
GOAL = {Width1 = 0}
local TWEEN = TWEEN_SERVICE:Create(TRAIL.Beam, TweenInfo.new(1), GOAL)
TWEEN:Play()
game:GetService("Debris"):AddItem(TRAIL, 2)
game:GetService("Debris"):AddItem(BULLET, 5)
GOAL = nil
end
local parry_cooldown = false
function parry_()
coroutine.wrap(function()
if parry_cooldown then return end
parry_cooldown = true
task.wait(0.1)
local parry = parent.Humanoid.Animator:LoadAnimation(parent.Animations.Parry)
parry:Play()
parry:AdjustSpeed(0.65)
parent.character_values.is_parrying.Value = true
parry.Stopped:Wait()
parent.character_values.is_parrying.Value = false
task.wait(1.5)
parry_cooldown = false
end)()
end
function FIRE_(target)
local can_see = false
local enemy_hrp = target.Head
local origin = parent.HumanoidRootPart.Position
local table_ = {parent}
for i, player in pairs(workspace:GetDescendants()) do
if player:IsA("Model") and player:FindFirstChildOfClass("Humanoid") and player ~= parent then
local faction = player:FindFirstChild("faction")
if faction.Value == parent.faction.Value then
table.insert(table_, player)
end
end
end
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = table_
local direction = (enemy_hrp.Position - Vector3.new(0, 0.5, 0) - origin).Unit
local raycast = workspace:Raycast(origin, direction * 3000, params)
if raycast then
local model = raycast.Instance:FindFirstAncestorOfClass("Model")
if model then
local target_human = model:FindFirstChildOfClass("Humanoid")
if target_human then
can_see = true
end
end
end
if not can_see then return end
can_see = false
coroutine.wrap(function()
if cooldown then return end
cooldown = true
local number = math.random(5, 20)
for i = 1, number do
if AMMO <= 0 then
cooldown = true
is_reloading = true
local anim = parent.Humanoid.Animator:LoadAnimation(parent.Animations.Reload)
anim:Play()
task.wait(3)
AMMO = MAX_AMMO
cooldown = false
is_reloading = false
return
end
if human.Health <= 0 then return end
AMMO -= 1
local can_see = false
local enemy_hrp = target.Head
local origin = parent.HumanoidRootPart.Position
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {parent, parent["SCAR-H"]}
local direction = (enemy_hrp.Position - Vector3.new(0, 0.5, 0) - origin).Unit
local raycast = workspace:Raycast(origin, direction * 3000, params)
if raycast then
local model = raycast.Instance:FindFirstAncestorOfClass("Model")
if model then
local target_human = model:FindFirstChildOfClass("Humanoid")
if target_human then
can_see = true
end
end
end
if not can_see then
cooldown = false
return
end
parent.Humanoid.Animator:LoadAnimation(parent.Animations.Fire):Play()
for i, particle in pairs(parent["SCAR-H"].Components.MuzzleFlash:GetChildren()) do
if particle:IsA("ParticleEmitter") then
particle:Emit(20)
elseif particle:IsA("Sound") then
particle:Play()
end
end
local origin = parent.HumanoidRootPart.Position
local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Exclude
params.FilterDescendantsInstances = {parent, parent["SCAR-H"]}
local direction = (enemy_hrp.Position - Vector3.new(0, 0.5, 0) - origin).Unit
local raycast = workspace:Raycast(origin, direction * 3000, params)
if raycast then
CREATE_TRAIL_(origin, raycast.Position)
local model = raycast.Instance:FindFirstAncestorOfClass("Model")
if model then
local target_human = model:FindFirstChildOfClass("Humanoid")
if target_human then
target_human:TakeDamage(DAMAGE)
if players:GetPlayerFromCharacter(target_human.Parent) then
screenShakeEvent:FireClient(players:GetPlayerFromCharacter(target_human.Parent), 3, false)
end
end
end
else
CREATE_TRAIL_(origin, direction)
end
task.wait(0.1)
end
task.wait(number/10)
cooldown = false
end)()
end
local target_goal
function backwards_()
target_goal = target_goal.HumanoidRootPart
task.spawn(function()
local number = math.random(1, 2)
if number == 1 then
moving_backwards = true
local direction = (parent.HumanoidRootPart.Position - target_goal.Position).Unit
parent.Humanoid.AutoRotate = false
parent.Humanoid:MoveTo(parent.HumanoidRootPart.Position + direction * 10)
task.wait(2)
if not parent.Humanoid.MoveToFinished then
parent.Humanoid.WalkSpeed = 0
moving_backwards = false
parent.Humanoid.AutoRotate = true
return
end
parent.Humanoid.MoveToFinished:Wait()
moving_backwards = false
parent.Humanoid.AutoRotate = true
else
moving_backwards = true
parent.Humanoid.AutoRotate = false
parent.Humanoid:MoveTo(parent.HumanoidRootPart.CFrame.RightVector * 5)
task.wait(2)
if not parent.Humanoid.MoveToFinished then
parent.Humanoid.WalkSpeed = 0
moving_backwards = false
parent.Humanoid.AutoRotate = true
return
end
parent.Humanoid.MoveToFinished:Wait()
moving_backwards = false
parent.Humanoid.AutoRotate = true
end
end)
end
local HRP = parent.HumanoidRootPart
local bodyGyro = Instance.new("BodyGyro")
bodyGyro.Parent = HRP
bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)
function loop_()
if human. Health <= 0 then return end
local target = findTarget()
if target then
if target.Humanoid.Health <= 0 then
if not table.find(ignore, target) then
table.insert(ignore, target)
end
return
end
aware = true
if aware then
aware = true
local goal
goal = target:WaitForChild("HumanoidRootPart").Position
bodyGyro.CFrame = CFrame.new(HRP.Position, goal)
local path = pathModule.new(parent)
path.Visualize = false
path.Blocked:Connect(function()
if not moving_backwards then
path:Run(goal)
end
end)
path.WaypointReached:Connect(function()
if not moving_backwards then
path:Run(goal)
end
end)
path.Error:Connect(function(errorType)
if not moving_backwards then
path:Run(goal)
end
end)
if not moving_backwards then
path:Run(goal)
end
if (parent.HumanoidRootPart.Position - goal).Magnitude < 100 then
FIRE_(target)
end
if (parent.HumanoidRootPart.Position - goal).Magnitude < 10 then
target_goal = target
parry_()
coroutine.resume(coroutine.create(backwards_))
end
end
end
end
while task.wait() do
loop_()
end