I’m currently working on an AI who walks through a maze at random waypoints and attacks players when it spots them, the AI works fine around 60% of the time and the main issue is that it sometimes gets stuck and is unable to compute a new path, this only happens once the AI is after the player and the player starts making sharp turns or moving around a lot which causes the AI to get confused and start moving into walls instead of continuing to go after the player. Here is my current code for the AI is there anything I could do to improve the code?
local humanoid = monster.Humanoid
local PathFindingService = game:GetService("PathfindingService")
monster.PrimaryPart:SetNetworkOwner(nil)
local function canSeeTarget(target)
local origin = monster.HumanoidRootPart.Position
local direction = (target.HumanoidRootPart.Position - monster.HumanoidRootPart.Position).unit * 80 --multiply the max distance
local ray = Ray.new(origin, direction)
local hit, pos = workspace:FindPartOnRay(ray, monster)
if hit then
if hit:IsDescendantOf(target) then
return true
end
else
return false
end
end
local function findTarget()
local players = game.Players:GetPlayers()
local maxdistance = 80
local nearesTarget
for index, player in pairs(players) do
if player.Character then
local target = player.Character
local distance = (monster.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance < maxdistance and canSeeTarget(target) then
nearesTarget = target
maxdistance = distance
end
end
end
return nearesTarget
end
local function getPath(destination)
local pathParams = {
["AgentHeight"] = 14.2,
["AgentRadius"] = 2, --might need to change
["AgentCanJump"] = false
}
local path = PathFindingService:CreatePath(pathParams)
path:ComputeAsync(monster.HumanoidRootPart.Position, destination.Position)
return path
end
local function attack(target)
local distance = (monster.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
if distance > 10 then
humanoid:MoveTo(target.HumanoidRootPart.Position)
else
target.Humanoid.Health = 0 -- kill player
end
end
local function walkTo(destination)
local path = getPath(destination)
if path.Status == Enum.PathStatus.Success then
for index, waypoint in pairs(path:GetWaypoints()) do
local target = findTarget()
if target and target.Humanoid.Health > 0 then
attack(target)
print(target.Name)
break
else
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
end
end
else
humanoid:MoveTo(destination.Position - (monster.HumanoidRootPart.CFrame.LookVector * 30))
end
end
local function patrol()
local waypoints = workspace.waypoints:GetChildren()
local randomnum = math.random(1, #waypoints)
walkTo(waypoints[randomnum])
end
while wait(0.25) do
patrol()
end