- What do you want to achieve? Keep it simple and clear!
I’ve been working on an advanced AI pathing script for caves. And I want to perfect it so it follows the player seamlessly.
- What is the issue? Include screenshots / videos if possible!
So I have a working script so far, but the AI is a bit delayed on updating to the players current position. I’ll send a video for reference. I’ll also send the script to see anyone can see any faults.
I’ve used a lot of resources from the Developer Hup already but I am still quite new to coding.
Code is here:
local Players = game:GetService("Players")
local Pathfinding = game:GetService("PathfindingService")
local RunSerivce = game:GetService("RunService")
local Entity = script.Parent
local rig = Entity.Humanoid:FindFirstChild("Animator")
local Root = Entity:FindFirstChild("HumanoidRootPart")
local alignOrientation = Root:FindFirstChild("AlignOrientation")
-- Pathfinding AI
local Humanoid = Entity:WaitForChild("Humanoid")
Entity.PrimaryPart:SetNetworkOwner(nil)
local recompute = true
local pathUpdate = false
local waypoints
local nextWaypointindx
local reachConnection
local blockedConnection = nil
local Walkspeed = Entity:GetAttribute("Walkspeed")
local SprintSpeed = Entity:GetAttribute("SprintSpeed")
local Damage = Entity:GetAttribute("Damage")
local Stopping = Entity:GetAttribute("Stop")
local function getPath(destination)
local path = Pathfinding:CreatePath({
AgentHeight = 4,
AgentRadius = 5,
AgentCanClimb = true,
AgentCanJump = true,
Costs = {
Water = math.huge
}
})
path:ComputeAsync(Root.Position, destination.Position)
return path
end
local function findTarget()
local nearestTarget
local MaxDistance = 100
for index, player in pairs(Players:GetPlayers()) do
if player.Character then
local target = player.Character
local distance = (Root.Position - target.HumanoidRootPart.Position).Magnitude
if distance < MaxDistance then
nearestTarget = target
MaxDistance = distance
end
end
end
return nearestTarget
end
local Cooldown = 3
local Debounce = false
local function attack()
local connection
connection = Entity.Humanoid.Touched:Connect(function(hit)
if not Debounce and hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Humanoid.Health > 0 then
Debounce = true
connection:Disconnect()
Entity.Humanoid.WalkSpeed = Stopping
Attack:Play()
task.wait(0.5)
hit.Parent.Humanoid:TakeDamage(10)
print("You've been hit")
task.spawn(function()
task.wait(Cooldown)
Debounce = false
end)
Attack:Stop()
Entity.Humanoid.WalkSpeed = Walkspeed
end
end)
end
local function TargetPosition(target)
local oldposition = target.HumanoidRootPart.Position
if oldposition == nil then
recompute = true;
else
if (oldposition - target.HumanoidRootPart.Position).Magnitude > 2 then
recompute = true
oldposition = target.HumanoidRootPart.Position
end
end
end
local function Capture(target)
local distance = (Root.Position - target.HumanoidRootPart.Position).Magnitude
while true do
local NewPath = Pathfinding:CreatePath({
AgentHight = 4,
AgentRadius = 5,
AgentCanClimb = true,
AgentCanJump = true,
Costs = {
Water = math.huge
}
})
if pathUpdate then
return
end
pathUpdate = true
if recompute then
local success, failure = pcall(function()
NewPath:ComputeAsync(Root.Position, target.HumanoidRootPart.Position)
end)
if distance > 5 and target.Humanoid.Health > 0 then
if success and NewPath.Status == Enum.PathStatus.Success then
waypoints = NewPath:GetWaypoints()
if blockedConnection == nil then
blockedConnection = NewPath.Blocked:Connect(function(blockedindex)
if recompute then
blockedConnection:Disconnect()
blockedConnection = nil
else
if blockedindex >= nextWaypointindx then
recompute = true
blockedConnection:Disconnect()
blockedConnection = nil
end
end
end)
end
nextWaypointindx = 2
for index, target in pairs(NewPath:GetWaypoints()) do
if not Walk.IsPlaying then
Walk:Play()
end
Humanoid:MoveTo(target.Position)
Humanoid.MoveToFinished:Wait()
end
else
Humanoid:MoveTo(target.Position - (Root.CFrame.LookVector * 10))
end
else
attack()
end
end
pathUpdate = false
task.wait(0.01)
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
TargetPosition(target)
Capture(target)
break
else
Entity.Humanoid.WalkSpeed = Walkspeed
Humanoid:MoveTo(waypoint.Position)
Humanoid.MoveToFinished:Wait()
end
end
else
Humanoid:MoveTo(destination.Position - (Root.CFrame.LookVector * 10))
end
end
local function Patrol()
local waypoints = workspace.Waypoints:GetChildren()
local ranWaypoint = math.random(1, #waypoints)
walkTo(waypoints[ranWaypoint])
end
attack()
while true do
Patrol()
task.wait(0.01)
end
Example gif here