Hello, I have been coding a Roblox script about a zombie npc for my game but when there are several instances of the zombie it starts to have strange movement like it walks looking to the side and with very unstable movement, here is the script I am having issues:
local PathfindingService = game:GetService("PathfindingService")
local RunService = game:GetService("RunService")
local npc = script.Parent
local humanoid = npc:WaitForChild("Humanoid")
local target = nil
local lastJumpTime = 0
local jumpCooldown = 2 -- Time in seconds between jumps
local lastAttackTime = 0
local attackCooldown = 3 -- Time in seconds between attacks
local attackRange = 5 -- Attack range in studs
local attackAnimations = script:WaitForChild("AttackAnimations"):GetChildren()
-- Function to find the closest player
local function findClosestPlayer()
local closestPlayer = nil
local shortestDistance = math.huge
for _, player in pairs(game.Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local distance = (npc.HumanoidRootPart.Position - player.Character.HumanoidRootPart.Position).magnitude
if distance < shortestDistance then
closestPlayer = player
shortestDistance = distance
end
end
end
return closestPlayer
end
-- Function to play a random attack animation
local function playRandomAttackAnimation()
local randomIndex = math.random(1, #attackAnimations)
local animation = attackAnimations[randomIndex]
local animator = humanoid:FindFirstChildOfClass("Animator")
if animator then
local animationTrack = animator:LoadAnimation(animation)
animationTrack:Play()
end
end
-- Function to attack the player
local function attackPlayer()
local currentTime = tick()
if currentTime - lastAttackTime >= attackCooldown then
if target and target.Character and target.Character:FindFirstChild("Humanoid") then
local targetHumanoid = target.Character.Humanoid
local distanceToTarget = (npc.HumanoidRootPart.Position - target.Character.HumanoidRootPart.Position).magnitude
if distanceToTarget <= attackRange then
targetHumanoid:TakeDamage(10) -- Damage dealt by the NPC
playRandomAttackAnimation()
lastAttackTime = currentTime
end
end
end
end
-- Function to move the NPC towards the player
local function moveToPlayer()
if target and target.Character and target.Character:FindFirstChild("HumanoidRootPart") then
local path = PathfindingService:CreatePath({
AgentRadius = 2,
AgentHeight = 5,
AgentCanJump = true,
AgentJumpHeight = 7,
AgentMaxSlope = 45,
})
path:ComputeAsync(npc.HumanoidRootPart.Position, target.Character.HumanoidRootPart.Position)
local waypoints = path:GetWaypoints()
for _, waypoint in pairs(waypoints) do
humanoid:MoveTo(waypoint.Position)
humanoid.MoveToFinished:Wait()
if waypoint.Action == Enum.PathWaypointAction.Jump and humanoid:GetState() ~= Enum.HumanoidStateType.Jumping then
local currentTime = tick()
if currentTime - lastJumpTime >= jumpCooldown and humanoid:GetState() == Enum.HumanoidStateType.Running then
humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
lastJumpTime = currentTime
end
end
end
end
end
-- Main loop
RunService.Heartbeat:Connect(function()
if humanoid.Health > 0 then
target = findClosestPlayer()
if target then
moveToPlayer()
attackPlayer()
end
end
end)
To understand my problem, here are videos
The video of the problem:
Another video but with more instances:
Sometimes I even get the same problem with just one instance.