I want the Zombie to continue walking no matter what.
Pathfinding Script:
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local zombieDamage = 10 --attack damage dealed to player
local zombieAttackCd = 3 --cooldown time before next attack
local rig = script.Parent
local function checkForCharacter(character)
local rayOrigin = rig:FindFirstChild("HumanoidRootPart").Position
local rayDirection = (character.HumanoidRootPart.Position - rayOrigin).Unit * 40
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, RaycastParams.new())
if raycastResult then
local raycastInstance = raycastResult.Instance
if raycastInstance:IsDescendantOf(character) then
return true
end
else
return false
end
end
local function findNearestPlayer()
local players = Players:GetPlayers()
local nearestPlayer = nil
local maxDistance = 40
for _, player in pairs(players) do
if player.Character ~= nil then
local targetCharacter = player.Character
local distance = (rig.HumanoidRootPart.Position - targetCharacter.HumanoidRootPart.Position).Magnitude
if distance < maxDistance and checkForCharacter(targetCharacter) then
nearestPlayer = targetCharacter
maxDistance = distance
end
end
end
return nearestPlayer
end
local function attack(character)
local cdTime = zombieAttackCd
local db = false
local distance = (rig.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Magnitude
if distance > 5 then
rig.Humanoid:MoveTo(character.HumanoidRootPart.Position)
else
if db == false then
character.Humanoid.Health -= zombieDamage
end
db = true
task.wait(cdTime)
end
end
local function calculatePath(destination)
local agentParams = {
["AgentHeight"] = 5,
["AgentRadius"] = 4,
["AgentCanJump"] = false
}
local path = PathfindingService:CreatePath(agentParams)
path:ComputeAsync(rig.HumanoidRootPart.Position, destination)
return path
end
local function walkToDestination(destination)
local path = calculatePath(destination)
if path.Status == Enum.PathStatus.Success then
for _, waypoint in pairs(path:GetWaypoints()) do
local nearestPlayer = findNearestPlayer()
if nearestPlayer then
attack(nearestPlayer)
break
else
rig.Humanoid:MoveTo(waypoint.Position)
rig.Humanoid.MoveToFinished:Wait()
end
end
else
rig.Humanoid:MoveTo(destination - (rig.HumanoidRootPart.CFrame.LookVector * 10))
end
end
local function patrol()
local waypoints = workspace.Waypoints:GetChildren()
local randomNumber = math.random(1, #waypoints)
walkToDestination(waypoints[randomNumber].Position)
end
while task.wait(.01) do
patrol()
if rig.Humanoid.Health == 0 then
rig:Destroy()
end
end
I fixed this script by moving the db variable outside of the attack function, and also by replacing task.wait(cdTime) with
task.defer(function()
task.wait(cdTime)
db = false
end)
The Completed Code is below:
local Players = game:GetService("Players")
local PathfindingService = game:GetService("PathfindingService")
local zombieDamage = 10 --attack damage dealed to player
local zombieAttackCd = 3 --cooldown time before next attack
local db = false
local rig = script.Parent
local function checkForCharacter(character)
local rayOrigin = rig:FindFirstChild("HumanoidRootPart").Position
local rayDirection = (character.HumanoidRootPart.Position - rayOrigin).Unit * 40
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, RaycastParams.new())
if raycastResult then
local raycastInstance = raycastResult.Instance
if raycastInstance:IsDescendantOf(character) then
return true
end
else
return false
end
end
local function findNearestPlayer()
local players = Players:GetPlayers()
local nearestPlayer = nil
local maxDistance = 40
for _, player in pairs(players) do
if player.Character ~= nil then
local targetCharacter = player.Character
local distance = (rig.HumanoidRootPart.Position - targetCharacter.HumanoidRootPart.Position).Magnitude
if distance < maxDistance and checkForCharacter(targetCharacter) then
nearestPlayer = targetCharacter
maxDistance = distance
end
end
end
return nearestPlayer
end
local function attack(character)
local cdTime = zombieAttackCd
local distance = (rig.HumanoidRootPart.Position - character.HumanoidRootPart.Position).Magnitude
if distance > 5 then
rig.Humanoid:MoveTo(character.HumanoidRootPart.Position)
else
if db == false then
character.Humanoid.Health -= zombieDamage
end
db = true
task.defer(function()
task.wait(cdTime)
db = false
end)
end
end
local function calculatePath(destination)
local agentParams = {
["AgentHeight"] = 5,
["AgentRadius"] = 4,
["AgentCanJump"] = false
}
local path = PathfindingService:CreatePath(agentParams)
path:ComputeAsync(rig.HumanoidRootPart.Position, destination)
return path
end
local function walkToDestination(destination)
local path = calculatePath(destination)
if path.Status == Enum.PathStatus.Success then
for _, waypoint in pairs(path:GetWaypoints()) do
local nearestPlayer = findNearestPlayer()
if nearestPlayer then
attack(nearestPlayer)
break
else
rig.Humanoid:MoveTo(waypoint.Position)
rig.Humanoid.MoveToFinished:Wait()
end
end
else
rig.Humanoid:MoveTo(destination - (rig.HumanoidRootPart.CFrame.LookVector * 10))
end
end
local function patrol()
local waypoints = workspace.Waypoints:GetChildren()
local randomNumber = math.random(1, #waypoints)
walkToDestination(waypoints[randomNumber].Position)
end
while task.wait(.01) do
patrol()
if rig.Humanoid.Health == 0 then
rig:Destroy()
end
end
Just tested it in game and it works., good luck on your zombie AI!
I’m not sure but my guess is it could be something to do with your waypoint system as when I run around a zombie in game the same way you did, with only one way point in Waypoints he sometimes unlocks off of me and goes for the waypoint instead.
Thinking about it im probaly at the border of the radius (MaxDistance) so ye it decides do go back the the waypoint but really quickly i walk back into the radius making him choose hes Rival (Me) >:D