Heya there.
Working on a fan recreation of a game called “Noobs vs Zombies: Relish Reborn”. I’m currently working on the AI of the NPCs found within the game and I’m adding pathfinding using PathfindingService. The issue is that the NPC’s are only going towards the oldest waypoint.
Module
--[[SERVICES]]--
local PathfindingService = game:GetService("PathfindingService")
local CollectionService = game:GetService("CollectionService")
local Debris = game:GetService("Debris")
--[[GETTING THE MODEL FOLDER]]--
local NoobModels = script.Parent:WaitForChild("Noobs")
local ZombieModels = script.Parent:WaitForChild("Zombies")
--[[MODULE]]--
local MeleeNPC = {}
--//Creating new NPC
function MeleeNPC.Spawn(NPCName, NPCTeam, WeaponType, SpawnLocation)
--//What all the parameters mean:
--[[
NPCName = The name of the NPC, obviously.
NPCTeam = What team the NPC is in.
WeaponType = What weapon the NPC is using.
SpawnLocation = Where to spawn the NPC.
]]
local CheckIfExists = NPCName
--//Giving the NPC the correct model & weapon.
if NPCTeam == "Noob" then
for _, ExistingModel in pairs(NoobModels:GetChildren()) do
if ExistingModel:IsA("Model") and ExistingModel.Name == CheckIfExists then
--//Spawning the NPC
local NewNPC = ExistingModel:Clone()
NewNPC.Parent = game.Workspace
NewNPC:PivotTo(SpawnLocation * CFrame.new(0, 3, 0))
CollectionService:AddTag(NewNPC, NPCTeam)
NewNPC.PrimaryPart:SetNetworkOwner(nil)
--//Forcefield
local Forcefield = Instance.new("ForceField",NewNPC)
game:GetService("Debris"):AddItem(Forcefield, 5)
--//Giving AI to the NPC
task.spawn(function()
while task.wait() do
local Target = MeleeNPC.FindTargets(NewNPC)
if Target then
MeleeNPC.Pathfind(NewNPC, Target)
end
end
end)
end
end
elseif NPCTeam == "Zombie" then
for _, ExistingModel in pairs(ZombieModels:GetChildren()) do
if ExistingModel:IsA("Model") and ExistingModel.Name == CheckIfExists then
--//Spawning the NPC
local NewNPC = ExistingModel:Clone()
NewNPC.Parent = game.Workspace
NewNPC:PivotTo(SpawnLocation * CFrame.new(0, 3, 0))
CollectionService:AddTag(NewNPC, NPCTeam)
NewNPC.PrimaryPart:SetNetworkOwner(nil)
--//Forcefield
local Forcefield = Instance.new("ForceField",NewNPC)
game:GetService("Debris"):AddItem(Forcefield, 5)
--//Giving AI to the NPC
task.spawn(function()
while task.wait() do
local Target = MeleeNPC.FindTargets(NewNPC)
if Target then
MeleeNPC.Pathfind(NewNPC, Target)
end
end
end)
end
end
end
end
--//Target & Pathfinding
function MeleeNPC.FindTargets(NPCModel)
local Target = nil
local PrimaryPart = NPCModel.PrimaryPart
for _, PossibleEnemies in pairs(game.Workspace:GetChildren()) do
if PossibleEnemies:IsA("Model") and PossibleEnemies:FindFirstChildWhichIsA("Humanoid") then
local Humanoid = PossibleEnemies:FindFirstChildWhichIsA("Humanoid")
if Humanoid.Health <= 1 then
return
end
--//Getting the distance
if NPCModel:HasTag("Noob") then
local Distance = (PossibleEnemies.PrimaryPart.Position - PrimaryPart.Position).Magnitude
if Distance <= math.huge then
--//Having the NPC target the right NPC/Player (Making sure the NPC goes to enemy NPCs or Players basically)
if PossibleEnemies:HasTag("Zombie") and NPCModel:HasTag("Noob") then
Target = PossibleEnemies
end
end
elseif NPCModel:HasTag("Zombie") then
--//Having the NPC target the right NPC/Player (Making sure the NPC goes to enemy NPCs or Players basically)
if PossibleEnemies:HasTag("Noob") and NPCModel:HasTag("Zombie") then
Target = PossibleEnemies
end
end
end
end
return Target
end
function MeleeNPC.Pathfind(NPCModel, Target)
local Humanoid = NPCModel:FindFirstChild("Humanoid")
while task.wait(0.5) do
local Path = PathfindingService:CreatePath()
Path:ComputeAsync(NPCModel.PrimaryPart.Position, Target.PrimaryPart.Position)
if Path.Status == Enum.PathStatus.Success then
local Waypoints = Path:GetWaypoints()
for _, Waypoint in pairs(Waypoints) do
if Waypoint.Action == Enum.PathWaypointAction.Jump then
Humanoid.Jump = true
end
Humanoid:MoveTo(Waypoint.Position)
Humanoid.MoveToFinished:Wait(1)
end
else
-- If the path cannot be computed, try to find a new target
local newTarget = MeleeNPC.FindTargets(NPCModel)
if newTarget then
MeleeNPC.Pathfind(NPCModel, newTarget)
end
end
end
end
return MeleeNPC