pls help me help me help me help me help me
I made a zombie npc chase the player but whenever it gets close to the player while I am walking (regardless of if its faster than me) it will always lag a few studs behind.
I have tried to make it so that it cannot collide with my player, but it didnt work (I don’t understand collision groups)
Here is the code so far:
local replicatedStorage = game:GetService("ReplicatedStorage")
local debris = game:GetService("Debris")
local runService = game:GetService("RunService")
local physicsService = game:GetService("PhysicsService")
local zombieSettings = require(script.Parent.Settings)
local humanoid = script.Parent:WaitForChild("Humanoid")
local root = script.Parent:WaitForChild("Torso")
local head = script.Parent:WaitForChild("Head")
local animator = humanoid:WaitForChild("Animator")
local dead = false
local chasing = false
local targetPlayer = nil
local lostSightTime = 0
local wanderCooldown = 0
local soundCooldown = 0
local spottedRecently = false
local clone = script.Parent:Clone()
local sprintAnim = replicatedStorage.animations.zombie.movement:WaitForChild("sprintAnim")
local idleAnim = replicatedStorage.animations.zombie.movement:WaitForChild("idleAnim")
local sprintTrack = animator:LoadAnimation(sprintAnim)
local idleTrack = animator:LoadAnimation(idleAnim)
humanoid.WalkSpeed = zombieSettings.movement.walk.walkSpeed
pcall(function()
physicsService:CreateCollisionGroup("Zombies")
physicsService:CreateCollisionGroup("Players")
end)
physicsService:CollisionGroupSetCollidable("Zombies", "Players", false)
for _, part in ipairs(script.Parent:GetDescendants()) do
if part:IsA("BasePart") then
physicsService:SetPartCollisionGroup(part, "Zombies")
end
end
local function playRandomSound(listName)
local sounds = zombieSettings.sounds[listName]
if sounds and #sounds > 0 then
local soundId = sounds[math.random(1,#sounds)]
local s = Instance.new("Sound")
s.SoundId = soundId
s.Parent = head
s:Play()
debris:AddItem(s, 6)
end
end
local function isInFOV(targetPosition)
local forward = root.CFrame.LookVector
local toTarget = (targetPosition - root.Position).Unit
return forward:Dot(toTarget) >= 0.1736
end
local function findPlayer()
local range = 50
local closest = nil
local closestDist = range + 1
for _, player in ipairs(game.Players:GetPlayers()) do
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local targetRoot = player.Character.HumanoidRootPart
local distance = (root.Position - targetRoot.Position).Magnitude
if distance <= range and isInFOV(targetRoot.Position) then
closest = targetRoot
closestDist = distance
end
end
end
return closest
end
local function startChasing(playerRoot)
targetPlayer = playerRoot
chasing = true
humanoid.WalkSpeed = zombieSettings.movement.sprint.walkSpeed
if not sprintTrack.IsPlaying then sprintTrack:Play(0.5) end
if not spottedRecently then
playRandomSound("spotted")
spottedRecently = true
soundCooldown = 5
end
end
local function stopChasing()
targetPlayer = nil
chasing = false
spottedRecently = false
humanoid.WalkSpeed = zombieSettings.movement.walk.walkSpeed
if sprintTrack.IsPlaying then sprintTrack:Stop() end
if not idleTrack.IsPlaying then idleTrack:Play(0.5) end
end
local function wander()
if chasing then return end
local randX = math.random(-50, 50)
local randZ = math.random(-50, 50)
local goal = root.Position + Vector3.new(randX, 0, randZ)
humanoid:MoveTo(goal)
end
runService.Heartbeat:Connect(function(dt)
if dead or humanoid.Health <= 0 then return end
local playerRoot = findPlayer()
if playerRoot then
startChasing(playerRoot)
lostSightTime = 0
elseif targetPlayer then
lostSightTime = lostSightTime + dt
if lostSightTime >= 10 then
stopChasing()
end
elseif not chasing then
wanderCooldown = wanderCooldown - dt
if wanderCooldown <= 0 then
wander()
wanderCooldown = 3 + math.random() * 2
end
end
soundCooldown = soundCooldown - dt
if soundCooldown <= 0 then
if chasing then
playRandomSound("chasing")
else
playRandomSound("idle")
end
soundCooldown = 5
end
if chasing and targetPlayer and targetPlayer.Parent then
local targetRoot = targetPlayer
local toZombie = (root.Position - targetRoot.Position)
local distance = toZombie.Magnitude
local playerLook = targetRoot.CFrame.LookVector
local offsetDistance = math.clamp(distance / 2, 2, 6)
local chasePosition = targetRoot.Position - (playerLook * offsetDistance)
humanoid:MoveTo(chasePosition)
end
end)
humanoid.Died:Connect(function()
dead = true
sprintTrack:Stop()
playRandomSound("death")
wait(20)
clone.Parent = workspace
debris:AddItem(script.Parent, 0.1)
end)