hello, I have a Pathfinding Ai script and there’s a problem with it, whenever a Player is getting chased by the Ai and the Ai looses sight of the player, the Ai turns away but then goes back to chasing the player. I need it where the Ai doesn’t jerk away after a player turns a corner then goes back to the chase the player, it shouldn’t do that. Any Help?
local Dummy = script.Parent
local Humanoid = Dummy.Humanoid
local IsPatrolling = true
Dummy.PrimaryPart:SetNetworkOwner(nil)
-- // Pathfinding variables \\--
local Rand = Random.new()
local Waypoints = workspace.Area.Waypoints:GetChildren()
local RaycastLength = 70
local AutoDetectRadius = 20
local PlayersInSafeRoom = require(script.SafeRoomHandler)
local PathfindingService = game:GetService("PathfindingService")
local PathParams = {
["AgentHeight"] = 9,
["AgentRadius"] = 6,
["AgentCanJump"] = false
}
local LastTarget
local HasTarget = false
local LastSeen
-- // Raycast Param \\ --
local RaycastParam = RaycastParams.new()
RaycastParam.FilterDescendantsInstances = {Dummy}
RaycastParam.FilterType = Enum.RaycastFilterType.Blacklist
local function CanSeeTarget(Target)
local origin = Dummy.PrimaryPart.Position
local direction = (Target.PrimaryPart.Position - Dummy.PrimaryPart.Position)
-- If player is in not safe room
if not table.find(PlayersInSafeRoom, Target) then
-- Cast ray to check walls
local RaycastResult = workspace:Raycast(origin, direction + direction.Unit, RaycastParam)
if RaycastResult then
-- Hit something!
local Hit = RaycastResult.Instance
if Hit:IsDescendantOf(Target) then
-- No walls in between player and dummy, check if they're in front or near the player
if Dummy.PrimaryPart.CFrame.LookVector:Dot(direction) > 0 or direction.Magnitude < AutoDetectRadius then
-- Can see player!
return true
end
end
end
end
return false
end
local function FindTarget()
local Players = game:GetService("Players"):GetPlayers()
local MaxDistance = math.huge
local Nearest = nil
-- Get nearest player
for _, Player in pairs(Players) do
local Character = Player.Character
if Character then
if Character.Humanoid.Health > 0 then
local Distance = (Dummy.PrimaryPart.Position - Character.PrimaryPart.Position).Magnitude
if Distance < MaxDistance and CanSeeTarget(Character) then
Nearest = Character
MaxDistance = Distance
end
end
end
end
-- Check if it found a player
if Nearest then
HasTarget = true
LastTarget = Nearest
LastSeen = os.time()
return Nearest
else
--Check if it has found a player before
if LastTarget then
if os.time() - LastSeen < 4 then
-- Hasn't been 4s
return LastTarget
end
end
-- No players
LastTarget = nil
HasTarget = false
return nil
end
end
local function MoveTo(Destination, IsAttacking)
local Path = PathfindingService:CreatePath(PathParams)
Path:ComputeAsync(Dummy.PrimaryPart.Position, Destination.Position)
if Path.Status == Enum.PathStatus.Success then
for _, Waypoint in pairs(Path:GetWaypoints()) do
if HasTarget and not IsAttacking then
-- Stop when a target is found and only patrolling
return
end
-- Automatically break when he sees you again
if IsAttacking then
if CanSeeTarget(Destination.Parent) then
break
end
end
Humanoid:MoveTo(Waypoint.Position)
Humanoid.MoveToFinished:Wait()
end
end
end
local function Patrol()
if IsPatrolling then
local r = Rand:NextInteger(1, #Waypoints)
local Waypoint = Waypoints[r]
if not HasTarget then
MoveTo(Waypoint)
else
task.wait()
end
-- No need for infinite loops
Patrol()
end
end
local function Attack(Target)
local Distance = (Dummy.PrimaryPart.Position - Target.PrimaryPart.Position).Magnitude
if Distance > 2 then
if CanSeeTarget(Target) then
Humanoid:MoveTo(Target.PrimaryPart.Position)
else
MoveTo(Target.PrimaryPart, true)
-- Lose Target if he can't see you anymore
if not CanSeeTarget(Target) then
LastTarget = nil
end
end
else
Target.Humanoid.Health = 0
HasTarget = false
LastTarget = nil
end
end
local StartTargetting = coroutine.wrap(function()
while IsPatrolling do
local Target = FindTarget()
if Target then
Attack(Target)
end
task.wait()
end
end)
StartTargetting()
Patrol()