I'm trying to practice OOP with zombies. What it's supposed to do is check if a player is around them, NOT an NPC. It will check the magnitude of each player's characters, and chooses the character model with the least magnitude. Then it chases that player using pathfinding service. However, instead of doing that, it just moves to another NPC with the same name. I am using 2 module scripts and a regular script to make it work.
Script (Placed in ServerScriptService):
local replicatedStorage = game:GetService("ReplicatedStorage")
local zombieModel = workspace.Zombie
local Zombie = require(game:GetService("ServerScriptService").Modules.NPCModule.ZombieModule)
local newZombie = Zombie.new(zombieModel, "Zombie", workspace.Ground.Position + Vector3.new(0,10,0))
local model = newZombie.Model
local zombiePosition = model.HumanoidRootPart.Position
local targetPosition = nil
model.Humanoid.WalkSpeed = newZombie.Speed
model.Humanoid.Health = newZombie.Health
model.HumanoidRootPart.Position = newZombie.SpawnLocation
model.Parent = workspace
game.Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
print("reached")
game:GetService("RunService").Heartbeat:Connect(function()
targetPosition = newZombie:GetClosestTarget()
print(targetPosition)
if targetPosition and character.HumanoidRootPart.Position == targetPosition then
newZombie:FindTarget(zombiePosition, targetPosition)
end
end)
end)
end)
ZombieModule (Module script placed in ServerScriptService under a module called "NPCModule"):
local NPC = require(script.Parent)
local runService = game:GetService("RunService")
local replicatedStorage = game:GetService("ReplicatedStorage")
local PFS = game:GetService("PathfindingService")
local Zombie = {}
Zombie.__index = Zombie
function Zombie.new(model, zombieType, position)
local newZombie = NPC.new(model, position)
setmetatable(newZombie, Zombie)
if zombieType == "Zombie" then
print("is zombie")
newZombie.Speed = 15
newZombie.ZombieType = zombieType
print(newZombie.Model.Name)
print(newZombie.Model.HumanoidRootPart.Name)
end
return newZombie
end
function Zombie:GetClosestTarget()
local model = self.Model
if model then
print("not nil!")
end
local target = nil
local lowestMagnitudeTarget = nil
local lowestMagnitude = 99999999999999999
local targetPosition = nil
local zombiePosition = model.HumanoidRootPart.Position
for i, player in pairs(game.Players:GetPlayers()) do
local characterModel = player.Character
local hrpPosition = characterModel.HumanoidRootPart.Position
print(hrpPosition)
local magnitude = (hrpPosition - zombiePosition).Magnitude
if magnitude < lowestMagnitude and game.Players:GetPlayerFromCharacter(characterModel)then
lowestMagnitude = magnitude
lowestMagnitudeTarget = hrpPosition
end
end
target = lowestMagnitudeTarget
return target
end
function Zombie:FindTarget(zombiePosition, targetPosition)
local model = self.Model
local zombieHumanoid = model.Humanoid
local path = PFS:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = true,
AgentCanClimb = true,
Costs = {
Water = 20
}
})
while true do
path:ComputeAsync(zombiePosition, targetPosition)
if path.Status == Enum.PathStatus.Success then
for i, waypoint in pairs(path:GetWaypoints()) do
if waypoint.Action == Enum.PathWaypointAction.Jump then
zombieHumanoid:ChangeState(Enum.HumanoidStateType.Jumping)
end
zombieHumanoid:MoveTo(waypoint.Position)
zombieHumanoid.MoveToFinished:Wait()
end
end
end
end
return Zombie
NPCModule (Module script placed in ServerScriptService):
local NPC = {}
NPC.__index = NPC
function NPC.new(model, position)
local newNPC = {}
setmetatable(newNPC, NPC)
newNPC.Model = model:Clone()
newNPC.Health = 100
newNPC.Speed = 16
newNPC.InteractionDistance = 2
newNPC.SpawnLocation = position
return newNPC
end
return NPC
As always, thank you for your time.

1 comment
I usually add a BoolValue named "NPC" in any NPCs. You can use them to check using "if not Zombie:FindFirstChild("NPC") then" or something. Another idea is to use "game.Players:GetPlayerFromCharacter(model)" when checking for players so that if it isn't a player, it returns nil