I am using the ACS AI in my game and noticed that the pathfinding breaks when you get into a DriverSeat. A regular Seat is fine, but a DriverSeat is not. It does this on every vehicle(helicopter, car, etc.) in the game. I get an error from every enemy AI script saying “Argument 2 missing or nil” on this line of code:
path:ComputeAsync(zombie.Position, destinationObject)
It seems that it throws this error whether or not the enemy can see the player. The AI works perfectly fine after this error, except it does one game-breaking thing: start searching for the player. The enemies are supposed to stay in place until they see a player, and the opposite happens when the player gets in a DriverSeat. I’m not experienced at all with pathfinding, so I’m not sure what the problem could be. Any help?
Thanks,
SpeakerDev
The full script(just in case)
task.wait(10)
script.Parent:MakeJoints()
---------------------------------------------------------------|
------// SETTINGS //-------------------------------------------|
---------------------------------------------------------------|
local RegularWalkspeed = 0
local SearchingWalkspeed = 8
local ShootingWalkspeed = 4
local Spread = 4
local MinDistance = 50
local MaxInc = 16
local Mode = 2
---------------------------------------------------------------|
---------------------------------------------------------------|
---------------------------------------------------------------|
local Debris = game.Debris
local Engine = game.ReplicatedStorage:WaitForChild("ACS_Engine")
local Evt = Engine:WaitForChild("Events")
local ServerConfig = require(Engine.GameRules:WaitForChild("Config"))
local Settings = script.Parent.ACS_Modulo:WaitForChild("Config")
local Weapon = script.Parent:FindFirstChildOfClass("Tool")
local WeaponData = require(Weapon:WaitForChild("ACS_Settings"))
local ACS_Storage = workspace:WaitForChild("ACS_WorkSpace")
local Modules = Engine:WaitForChild("Modules")
local Hitmarker = require(Modules:WaitForChild("Hitmarker"))
local Ragdoll = require(Modules:WaitForChild("Ragdoll"))
local Ignore_Model = ACS_Storage:FindFirstChild("Server")
local BulletModel = ACS_Storage:FindFirstChild("Client")
local Ray_Ignore = {Ignore_Model, BulletModel, ACS_Storage}
local Dead = false
task.wait(3)
script.Parent.ForceField:Destroy()
script.Parent.Humanoid.Died:connect(function()
Ragdoll(script.Parent)
if script.Parent:FindFirstChild("Gun") ~= nil then
script.Parent.Gun.CanCollide = true
end
Dead = true
Debris:AddItem(script.Parent,game.Players.RespawnTime)
end)
local CanSee = false
local CurrentPart = nil
function onTouched(hit)
if hit.Parent == nil then
return
end
local humanoid = hit.Parent:findFirstChild("Humanoid")
if humanoid == nil then
CurrentPart = hit
end
end
function waitForChild(parent, childName)
local child = parent:findFirstChild(childName)
if child then
return child
end
while true do
--print(childName)
child = parent.ChildAdded:wait()
if child.Name==childName then
return child
end
end
end
local Figure = script.Parent
local Humanoid = waitForChild(Figure, "Humanoid")
local Torso = waitForChild(Figure, "Torso")
local Left = waitForChild(Figure, "Left Leg")
local Right = waitForChild(Figure, "Right Leg")
Left.Touched:connect(onTouched)
Right.Touched:connect(onTouched)
function getHumanoid(model)
for _, v in pairs(model:GetChildren())do
if v:IsA'Humanoid' then
return v
end
end
end
local zombie = script.Parent
local human = getHumanoid(zombie)
local hroot = zombie.Torso
local head = zombie:FindFirstChild'Head'
local pfs = game:GetService("PathfindingService")
local players = game:GetService('Players')
local RecoilSpread = Spread/100
local perception = 0
local Memory = 0
task.wait(.1)
local ammo=Settings.Ammo.Value -- How much ammo the Enemy has
local w=.14
local RPM = 1/(WeaponData.ShootRate/60)
local r=false
local t=script.Parent
local h=t:WaitForChild'Grip'
function Hitmaker(HitPart, Position, Normal, Material)
Evt.HitEffect:FireAllClients(nil, Position, HitPart, Normal, Material, WeaponData)
end
function CheckForHumanoid(L_225_arg1)
local L_226_ = false
local L_227_ = nil
if L_225_arg1 then
if (L_225_arg1.Parent:FindFirstChild("Humanoid") or L_225_arg1.Parent.Parent:FindFirstChild("Humanoid")) then
L_226_ = true
if L_225_arg1.Parent:FindFirstChild('Humanoid') then
L_227_ = L_225_arg1.Parent.Humanoid
elseif L_225_arg1.Parent.Parent:FindFirstChild('Humanoid') then
L_227_ = L_225_arg1.Parent.Parent.Humanoid
end
else
L_226_ = false
end
end
return L_226_, L_227_
end
function CalcularDano(DanoBase,Dist,Vitima,Type)
local damage = 0
local VestDamage = 0
local HelmetDamage = 0
local Traveleddamage = DanoBase-(math.ceil(Dist)/40)*WeaponData.DamageFallOf
if Vitima.Parent:FindFirstChild("Saude") ~= nil then
local Vest = Vitima.Parent.Saude.Protecao.VestVida
local Vestfactor = Vitima.Parent.Saude.Protecao.VestProtect
local Helmet = Vitima.Parent.Saude.Protecao.HelmetVida
local Helmetfactor = Vitima.Parent.Saude.Protecao.HelmetProtect
if Type == "Head" then
if Helmet.Value > 0 and (WeaponData.BulletPenetration) < Helmetfactor.Value then
damage = Traveleddamage * ((WeaponData.BulletPenetration)/Helmetfactor.Value)
HelmetDamage = (Traveleddamage * ((100 - WeaponData.BulletPenetration)/Helmetfactor.Value))
if HelmetDamage <= 0 then
HelmetDamage = 0.5
end
elseif Helmet.Value > 0 and (WeaponData.BulletPenetration) >= Helmetfactor.Value then
damage = Traveleddamage
HelmetDamage = (Traveleddamage * ((100 - WeaponData.BulletPenetration)/Helmetfactor.Value))
if HelmetDamage <= 0 then
HelmetDamage = 1
end
elseif Helmet.Value <= 0 then
damage = Traveleddamage
end
else
if Vest.Value > 0 and (WeaponData.BulletPenetration) < Vestfactor.Value then
damage = Traveleddamage * ((WeaponData.BulletPenetration)/Vestfactor.Value)
VestDamage = (Traveleddamage * ((100 - WeaponData.BulletPenetration)/Vestfactor.Value))
if VestDamage <= 0 then
VestDamage = 0.5
end
elseif Vest.Value > 0 and (WeaponData.BulletPenetration) >= Vestfactor.Value then
damage = Traveleddamage
VestDamage = (Traveleddamage * ((100 - WeaponData.BulletPenetration)/Vestfactor.Value))
if VestDamage <= 0 then
VestDamage = 1
end
elseif Vest.Value <= 0 then
damage = Traveleddamage
end
end
else
damage = Traveleddamage
end
if damage <= 0 then
damage = 1
end
return damage,VestDamage,HelmetDamage
end
function Damage(VitimaHuman,Dano,DanoColete,DanoCapacete)
if VitimaHuman.Parent:FindFirstChild("Saude") ~= nil then
local Colete = VitimaHuman.Parent.Saude.Protecao.VestVida
local Capacete = VitimaHuman.Parent.Saude.Protecao.HelmetVida
Colete.Value = Colete.Value - DanoColete
Capacete.Value = Capacete.Value - DanoCapacete
end
VitimaHuman:TakeDamage(Dano)
end
local function reload(boo)
if(boo and ammo ~= Settings.Ammo.Value)or ammo==0 then
r=true
if w then
w=.03
end
h.Reload:Play()
task.wait(3) -- How long the Enemy reloads
ammo= Settings.Ammo.Value
if w then
w=.14
end
r=false
elseif boo then
task.wait(.1)
end
end
local function near()
if not Dead then
local dis,pl= Settings.ShotDistance.Value ,nil -- Range of the Enemy
for _,v in ipairs(game.Players:GetPlayers())do
if v.Character and v.Character:FindFirstChild'Humanoid'and v:DistanceFromCharacter(h.Position)<dis then
dis,pl=v:DistanceFromCharacter(h.Position),v
end
end
if pl then
return pl.Character:GetModelCFrame(),dis,CFrame.new(pl.Character.Humanoid.WalkToPoint).lookVector
else
return nil
end
end
end
-- no touchy
local path = pfs:CreatePath()
local waypoint
local currentWaypointIndex
local target
function findNearestTorso(pos)
local list = game.Workspace:children()
local torso = nil
local dist = Settings.WalkDistance.Value
local temp = nil
local human = nil
local temp2 = nil
for x = 1, #list do
temp2 = list[x]
if (temp2.className == "Model") and (temp2 ~= script.Parent) then
temp = temp2:findFirstChild("HumanoidRootPart")
human = temp2:findFirstChild("Humanoid")
if (temp ~= nil) and (human ~= nil) and (human.Health > 0) and players:GetPlayerFromCharacter(human.Parent)~= nil then
if (temp.Position - pos).magnitude < dist then
torso = temp
dist = (temp.Position - pos).magnitude
end
end
end
end
return torso
end
--spawn(function()
--while task.wait()do
-------------------------------------------------------------------
-------------------------------------------------------------------
-------------------------------------------------------------------
local PathfindingService = game:GetService("PathfindingService")
-- Variables for the zombie, its humanoid, and destination
local zombie = hroot
local destination = nil
-- Create the path object
local path = PathfindingService:CreatePath()
-- Variables to store waypoints table and zombie's current waypoint
local waypoints
local currentWaypointIndex
local function followPath(destinationObject)
-- Compute and check the path
path:ComputeAsync(zombie.Position, destinationObject)
-- Empty waypoints table after each new path computation
waypoints = {}
if path.Status == Enum.PathStatus.Success then
-- Get the path waypoints and start zombie walking
waypoints = path:GetWaypoints()
-- Move to first waypoint
currentWaypointIndex = 1
human:MoveTo(waypoints[currentWaypointIndex].Position)
else
-- Error (path not found); stop humanoid
human:MoveTo(zombie.Position)
end
end
local function onWaypointReached(reached)
if reached and waypoints ~= nil and currentWaypointIndex ~= nil and currentWaypointIndex < #waypoints then
currentWaypointIndex = currentWaypointIndex + 1
human:MoveTo(waypoints[currentWaypointIndex].Position)
end
end
local function onPathBlocked(blockedWaypointIndex)
-- Check if the obstacle is further down the path
if blockedWaypointIndex > currentWaypointIndex then
-- Call function to re-compute the path
followPath(destination)
end
end
-- Connect 'Blocked' event to the 'onPathBlocked' function
path.Blocked:Connect(onPathBlocked)
-- Connect 'MoveToFinished' event to the 'onWaypointReached' function
human.MoveToFinished:Connect(onWaypointReached)
--followPath(destination)
-------------------------------------------------------------------
-------------------------------------------------------------------
-------------------------------------------------------------------
function AI()
if Mode == 0 then
--waypoint = nil
--print("Patrol mode")
task.wait(math.random(5,15)/10)
followPath(hroot.Position + Vector3.new(math.random(-MaxInc, MaxInc), 0, math.random(-MaxInc, MaxInc)))
--human:MoveTo(zombie.Torso.Position + Vector3.new(math.random(-MaxInc, MaxInc), 0, math.random(-MaxInc, MaxInc)), CurrentPart)
elseif Mode == 1 then
target = findNearestTorso(hroot.Position)
if target ~= nil then
if CanSee == true and (hroot.Position - target.Position).Magnitude <= MinDistance then
waypoint = nil
else
path:ComputeAsync(hroot.Position, target.Position)
waypoint = path:GetWaypoints()
local connection = nil
local function checkw(t)
local ci = 3
if ci > #t then
ci = 3
end
if t[ci] == nil and ci < #t then
repeat ci = ci + 1 task.wait() until t[ci] ~= nil
return Vector3.new(1,0,0) + t[ci]
else
ci = 3
return t[ci]
end
end
if path.Status == Enum.PathStatus.Success then
--print("Chasing "..target.Parent.Name)
human.WalkToPart = nil
if waypoint or checkw(waypoint) then
if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
human:MoveTo( checkw(waypoint).Position)
end
if connection then
connection:Disconnect()
end
else
for i = 3, #waypoint do
human:MoveTo( waypoint[i].Position )
end
end
else
--print("No Path,Patrolling")
task.wait(math.random(5,15)/10)
followPath(hroot.Position + Vector3.new(math.random(-MaxInc, MaxInc), 0, math.random(-MaxInc, MaxInc)))
end
end
end
elseif Mode == 2 then
target = findNearestTorso(hroot.Position)
if target ~= nil then
if CanSee == true and (hroot.Position - target.Position).Magnitude <= MinDistance then
waypoint = {}
waypoint = nil
else
path:ComputeAsync(hroot.Position, target.Position)
waypoint = path:GetWaypoints()
local connection = nil
local function checkw(t)
local ci = 3
if ci > #t then
ci = 3
end
if t[ci] == nil and ci < #t then
repeat ci = ci + 1 task.wait() until t[ci] ~= nil
return Vector3.new(1,0,0) + t[ci]
else
ci = 3
return t[ci]
end
end
if path.Status == Enum.PathStatus.Success and Memory > 0 then
--print("Chasing "..target.Parent.Name)
human.WalkToPart = nil
if waypoint or checkw(waypoint) then
if checkw(waypoint) ~= nil and checkw(waypoint).Action == Enum.PathWaypointAction.Walk then
human:MoveTo( checkw(waypoint).Position )
end
if connection then
connection:Disconnect()
end
else
for i = 3, #waypoint do
human:MoveTo( waypoint[i].Position )
end
end
else
waypoint = nil
--print("No Path,Patrolling")
task.wait(math.random(5,15)/10)
followPath(hroot.Position + Vector3.new(math.random(-MaxInc, MaxInc), 0, math.random(-MaxInc, MaxInc)))
end
end
end
elseif Mode == 3 then
-- print("Guarding")
end
end
--end)
task.spawn(function()
while true do
if Dead then
break
end
AI()
local n,mag,hum=near()
if n and not Dead then
n=n.p
if not r then
w=.14
local dir=h.Position-n
local tst ,_ =workspace:FindPartOnRay(Ray.new(t.Torso.Position,(n-t.Torso.Position).Unit*999),t)
local aim =n+Vector3.new(math.random(-mag*RecoilSpread,mag*RecoilSpread),math.random(-mag*RecoilSpread,mag*RecoilSpread),math.random(-mag*RecoilSpread,mag*RecoilSpread))+hum
if tst and not Dead then
local FoundHuman,VitimaHuman = CheckForHumanoid(tst)
if FoundHuman == true and VitimaHuman.Health > 0 and game.Players:GetPlayerFromCharacter(VitimaHuman.Parent) and perception >= 10 then
function lookAt(target, eye)
local forwardVector = (eye - target).Unit
local upVector = Vector3.new(0, 1, 0)
-- You have to remember the right hand rule or google search to get this right
local rightVector = forwardVector:Cross(upVector)
local upVector2 = rightVector:Cross(forwardVector)
return CFrame.fromMatrix(eye, rightVector, upVector2)
end
local direction = (n+hum)-h.CFrame.LookVector
script.Parent:SetPrimaryPartCFrame(CFrame.new(t.Head.CFrame.Position,Vector3.new(direction.X,h.CFrame.Y,direction.Z)))
Evt.ServerBullet:FireAllClients(nil, h.Position,(aim - h.Position).Unit,WeaponData,nil)
h.Echo:Play()
h.Fire:Play()
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = Ray_Ignore
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.IgnoreWater = true
local raycastResult = workspace:Raycast(h.Position, (aim - h.Position).Unit*999, raycastParams)
if raycastResult and raycastResult.Instance and not Dead then
Hitmaker(raycastResult.Instance, raycastResult.Position, raycastResult.Normal, raycastResult.Material)
local FoundHuman,VitimaHuman = CheckForHumanoid(raycastResult.Instance)
if FoundHuman == true and VitimaHuman.Health > 0 and game.Players:GetPlayerFromCharacter(VitimaHuman.Parent) then
local TotalDistTraveled = (raycastResult.Position - h.Position).Magnitude
------ How much damage the gun inflicts
if raycastResult.Instance.Name == "Head" or raycastResult.Instance.Parent.Name == "Top" or raycastResult.Instance.Parent.Name == "Headset" or raycastResult.Instance.Parent.Name == "Olho" or raycastResult.Instance.Parent.Name == "Face" or raycastResult.Instance.Parent.Name == "Numero" then
local DanoBase = math.random(WeaponData.HeadDamage[1], WeaponData.HeadDamage[2])
local Dano,DanoColete,DanoCapacete = CalcularDano(DanoBase, TotalDistTraveled, VitimaHuman, "Head")
Damage(VitimaHuman,Dano,DanoColete,DanoCapacete)
elseif (raycastResult.Instance.Parent:IsA('Accessory') or raycastResult.Instance.Parent:IsA('Hat')) then
local DanoBase = math.random(WeaponData.HeadDamage[1], WeaponData.HeadDamage[2])
local Dano,DanoColete,DanoCapacete = CalcularDano(DanoBase, TotalDistTraveled, VitimaHuman, "Head")
Damage(VitimaHuman,Dano,DanoColete,DanoCapacete)
elseif raycastResult.Instance.Name == "Torso" or raycastResult.Instance.Parent.Name == "Chest" or raycastResult.Instance.Parent.Name == "Waist" then
local DanoBase = math.random(WeaponData.TorsoDamage[1], WeaponData.TorsoDamage[2])
local Dano,DanoColete,DanoCapacete = CalcularDano(DanoBase, TotalDistTraveled, VitimaHuman, "Body")
Damage(VitimaHuman,Dano,DanoColete,DanoCapacete)
elseif raycastResult.Instance.Name == "Right Arm" or raycastResult.Instance.Name == "Left Arm" or raycastResult.Instance.Name == "Right Leg" or raycastResult.Instance.Name == "Left Leg" or raycastResult.Instance.Parent.Name == "Back" or raycastResult.Instance.Parent.Name == "Leg1" or raycastResult.Instance.Parent.Name == "Leg2" or raycastResult.Instance.Parent.Name == "Arm1" or raycastResult.Instance.Parent.Name == "Arm2" then
local DanoBase = math.random(WeaponData.LimbDamage[1], WeaponData.LimbDamage[2])
local Dano,DanoColete,DanoCapacete = CalcularDano(DanoBase, TotalDistTraveled, VitimaHuman, "Body")
Damage(VitimaHuman,Dano,DanoColete,DanoCapacete)
else
local DanoBase = math.random(WeaponData.LimbDamage[1], WeaponData.LimbDamage[2])
local Dano,DanoColete,DanoCapacete = CalcularDano(DanoBase, TotalDistTraveled, VitimaHuman, "Body")
Damage(VitimaHuman,Dano,DanoColete,DanoCapacete)
end
end
end
ammo=ammo-1
if raycastResult then
mag=(h.Position-raycastResult.Position).magnitude
end
t.Humanoid.WalkSpeed = ShootingWalkspeed
elseif FoundHuman == true and VitimaHuman.Health > 0 and game.Players:GetPlayerFromCharacter(VitimaHuman.Parent) and perception < 10 then
perception = perception + Settings.Level.Value
t.Humanoid.WalkSpeed = SearchingWalkspeed
Memory = Settings.Level.Value * 100
CanSee = true
elseif perception > 0 then
perception = perception - 1/Settings.Level.Value * 2
t.Humanoid.WalkSpeed = SearchingWalkspeed
CanSee = false
elseif perception <= 0 then
perception = 0
t.Humanoid.WalkSpeed = RegularWalkspeed
Memory = Memory - .25
end
--print(Memory)
end
task.wait(RPM) -- How fast the enemy shoots
if ammo==0 then
reload()
end
end
end
end
end)
-- 00Scorpion00