I have this code for AI which shoots the player and has a patrol behavior It works, however occasionally and I’m not certain what causes it, it will just run on the same place, while in the run animation, it fixes itself if you get within its attack range or if you get far enough away but still, for no reason it sometimes just get stuck in running on the spot, I tried to add fallbacks and they reduced how often it happens but it still does it.
Help is appreciated
task.wait(5)
local shootModule = require(game.ServerScriptService.NPCShoot)
local PathfindingService = game:GetService("PathfindingService")
local AI = script.Parent
local RP = script.Parent.HumanoidRootPart
local Hum = script.Parent.Humanoid
local Gun = script.Parent.Pistol
local Waypoints = game.Workspace:WaitForChild("Waypoints"):GetChildren()
RP:SetNetworkOwner(nil)
local attackAnim = Hum.Animator:LoadAnimation(script.Attack)
local walkAnim = Hum.Animator:LoadAnimation(script.Walk)
local runAnim = Hum.Animator:LoadAnimation(script.Run)
local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
rayParams.FilterDescendantsInstances = {Hum}
local Damage = 25
local AttackRange = 15
local shootTrack = AI.Humanoid.Animator:LoadAnimation(game.ReplicatedStorage.Animations.NPCPistolShoot)
walkAnim.Looped = true
runAnim.Looped = true
walkAnim:Play()
local LastSeenPos
local RayParams = RaycastParams.new()
RayParams.FilterType = Enum.RaycastFilterType.Exclude
local pathParams = {
AgentHeight = 5,
AgentRadius = 3,
AgentCanJump = true,
}
local function getPath(destination)
if destination then
print('Get path fired')
local path = PathfindingService:CreatePath(pathParams)
path:ComputeAsync(RP.Position, destination)
return path
else
patrol()
return "Fail"
end
end
function lineOfSight(target)
local rayDirection = target.Position - RP.Position
local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = {RP.Parent}
local RayResult = workspace:Raycast(RP.Position, rayDirection, rayParams)
if RayResult and RayResult.Instance then
if RayResult.Instance:IsDescendantOf(target.Parent) then
return true
else
return false
end
end
end
function shoot()
end
function getTarget()
local closestTarget
local distanceFromClosestTarget = 1000000000
for i, player in pairs(game.Players:GetChildren()) do
local distance = (player.Character.HumanoidRootPart.Position - RP.Position).Magnitude
if distance < distanceFromClosestTarget then
distanceFromClosestTarget = distance
closestTarget = player
end
end
return(closestTarget)
end
local db = false
local runAnimPlayingStatus = false
local walkAnimPlayingStatus = false
function chaseTarget(target)
if runAnimPlayingStatus == false then
walkAnim:Stop()
runAnim:Play()
runAnimPlayingStatus = true
walkAnimPlayingStatus = false
end
local path
path = getPath(target.Character.HumanoidRootPart.Position)
if path ~= "Fail" then
local waypoints = path:GetWaypoints()
if waypoints[2] then
Hum:MoveTo(waypoints[2].Position)
local humTarget = getTarget()
local LineOfSight = lineOfSight(humTarget.Character.HumanoidRootPart)
LastSeenPos = humTarget.Character.HumanoidRootPart.Position
if (humTarget.Character.HumanoidRootPart.Position - RP.Position).Magnitude <= 20 and db == false then
if AI.Humanoid.Health > 0 and Gun:GetAttribute("Reloading") == false then
runAnim:Stop()
shootTrack:Play()
db = true
shootModule.Shoot(target, Gun, AI)
runAnim:Play()
task.delay(1, function()
db = false
end)
patrol()
else
--patrol()
end
end
if humTarget and LineOfSight then
chaseTarget(humTarget)
else
moveToLastSeen(LastSeenPos)
end
else
local ChosenWapoint = math.random(1, #Waypoints)
moveTo(game.Workspace.Waypoints:FindFirstChild(ChosenWapoint).Position)
warn("Path Failed to compute falling back")
moveTo()
end
else
local ChosenWapoint = math.random(1, #Waypoints)
moveTo(game.Workspace.Waypoints:FindFirstChild(ChosenWapoint).Position)
warn("Path Failed to compute falling back")
moveTo()
end
end
function moveToLastSeen(location)
local path = getPath(location)
if path ~= "Fail" then
for i, waypoint in pairs(path:GetWaypoints()) do
local humTarget = getTarget()
local LineOfSight = lineOfSight(humTarget.Character.HumanoidRootPart)
if humTarget and LineOfSight then
path:Destroy()
chaseTarget(humTarget)
break
else
if walkAnimPlayingStatus == false then
walkAnim:Play()
walkAnimPlayingStatus = true
end
runAnimPlayingStatus = false
runAnim:Stop()
Hum:MoveTo(waypoint.Position)
Hum.MoveToFinished:Wait()
if i == #path:GetWaypoints() then
patrol()
end
end
end
else
local ChosenWapoint = math.random(1, #Waypoints)
moveTo(game.Workspace.Waypoints:FindFirstChild(ChosenWapoint).Position)
warn("Path Failed to compute falling back")
moveTo()
end
end
function moveTo(target)
local humTarget = getTarget()
local LineOfSight = lineOfSight(humTarget.Character.HumanoidRootPart)
if humTarget and LineOfSight then
chaseTarget(humTarget)
else
local path = getPath(target)
if path.Status == Enum.PathStatus.Success then
for i, waypoint in pairs(path:GetWaypoints()) do
local humTarget = getTarget()
local LineOfSight = lineOfSight(humTarget.Character.HumanoidRootPart)
if humTarget and LineOfSight then
path:Destroy()
chaseTarget(humTarget)
break
else
if walkAnimPlayingStatus == false then
walkAnim:Play()
walkAnimPlayingStatus = true
end
runAnimPlayingStatus = false
runAnim:Stop()
Hum:MoveTo(waypoint.Position)
Hum.MoveToFinished:Wait()
if i == #path:GetWaypoints() then
patrol()
end
end
end
end
end
end
function patrol()
local ChosenWapoint = math.random(1, #Waypoints)
moveTo(game.Workspace.Waypoints:FindFirstChild(ChosenWapoint).Position)
end
script.Parent.Humanoid.Died:Connect(function()
script:Destroy()
end)
patrol()