Hello, I am trying to make a round based game with zombies. The issue comes when teleporting the player, the zombies act as if the player model is in an old spot, but it is in the new spot, the spot the player teleported to when the round began. I do not know why this has happened, as the zombie code detects collision with players by checking if the model has a humanoid, and if it does it will check if the model name matches with any player names in the player chunk in studio.
Zombie Hit Detection & Damaging Code
zombie = script.Parent
zomHRP = zombie:FindFirstChild("HumanoidRootPart")
Player = game:GetService("Players")
config = zombie:FindFirstChild("Configuration")
MaxDamage = config.MaxDamage.Value
MinDamage = config.MinDamage.Value
MaxAttackCD = config.MaxAttackCD.Value
MinAttackCD = config.MinAttackCD.Value
debounce4Attack = true
zomHRP.Touched:Connect(function(hit)
local human = hit.Parent:FindFirstChildWhichIsA("Humanoid") or hit.Parent.Parent:FindFirstChildWhichIsA("Humanoid")
if human ~= nil and debounce4Attack == true then
if game.Players:FindFirstChild(human.Parent.Name) ~= nil then
debounce4Attack = false
human.Health -= (math.random(MinDamage,MaxDamage))
task.wait((math.random(MinAttackCD,MaxAttackCD))/10)
debounce4Attack = true
end
end
end)
Some stuff to add:
The player teleport code runs on the side of the server in the GameHandlerScript, which I have tested many times. It is NOT the player teleportation.
Both zombie and player models are with R15.
To solve the issue with the zombies going to where the player used to be, we would need to see the script for zombie path finding. The code that tells the zombies where to move to.
And for teleporting issues, we would need to see the teleporting script. The code that places the player in the map.
As for the zombie attack code (the code you posted) I didn’t see anything wrong with it.
However, I did clean it up for you here…
zombie = script.Parent
zomHRP = zombie:WaitForChild("HumanoidRootPart")
Players = game:GetService("Players")
config = zombie:FindFirstChild("Configuration")
MaxDamage = config.MaxDamage.Value
MinDamage = config.MinDamage.Value
MaxAttackCD = config.MaxAttackCD.Value
MinAttackCD = config.MinAttackCD.Value
debounce4Attack = true
zomHRP.Touched:Connect(function(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player then
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid then
debounce4Attack = false
humanoid.Health -= (math.random(MinDamage,MaxDamage))
task.wait((math.random(MinAttackCD,MaxAttackCD))/10)
debounce4Attack = true
end
end
end)
The issue might be because you are not updating the players position when they player moves.
I would say to fix this you can either update the zombies to stop moving if the players aren’t within a certain range, or to check if the players is in a spot where the zombie can get to, else if not to stop. This does cause lag however if you are using a loop so make sure to only send out a signal to stop moving when necessary.
This is the code for finding and pathfinding to the player.
Player = game:GetService("Players")
Pathfinding = game:GetService("PathfindingService")
zombie = script.Parent
zomHRP = zombie:FindFirstChild("HumanoidRootPart")
zomHum = zombie:FindFirstChild("Humanoid")
zomHead = zombie:FindFirstChild("Head")
config = zombie:FindFirstChild("Configuration")
MaxDamage = config.MaxDamage.Value
MinDamage = config.MinDamage.Value
MaxAttackCD = config.MaxAttackCD.Value
MinAttackCD = config.MinAttackCD.Value
MaxSmellRange = config.MaxSmellRange.Value
MinSmellRange = config.MinSmellRange.Value
MaxSightRange = config.MaxSightRange.Value
MinSightRange = config.MinSightRange.Value
BlindSight = config.BlindSight.Value
SightRange = 100 -- math.random(MinSightRange, MaxSightRange)
SmellRange = math.random(MinSmellRange, MaxSmellRange)
function findPlayerWithSmell()
XYZtemp = nil
for _,plr in pairs(Player:GetPlayers()) do
if plr then
local plrCharacter = plr.Character
if plrCharacter then
local humanoid = plrCharacter:FindFirstChildWhichIsA("Humanoid")
if humanoid and humanoid.Health > 0 then
local plrRoot = plrCharacter:FindFirstChild("HumanoidRootPart")
if plrRoot then
local distance = (plrRoot.Position - zomHRP.Position).Magnitude
if distance < SmellRange then
XYZtemp = plrCharacter
chasePlayer()
end
end
end
end
end
end
end
function chasePlayer()
local plr = game.Workspace:WaitForChild(XYZtemp.Name) or game.Workspace:WaitForChild(ABCtemp.Name)
local Path = Pathfinding:CreatePath({
AgentRadius = 3,
AgentHeight = 6,
AgentCanJump = true,
WaypointSpacing = 1
})
Path:ComputeAsync(zomHRP.Position, plr:WaitForChild("HumanoidRootPart").Position)
local waypoints = Path:GetWaypoints()
for i = 1, #waypoints do
if waypoints[i].Action == Enum.PathWaypointAction.Jump then
zomHum:MoveTo(waypoints[i].Position)
zomHum:ChangeState(Enum.HumanoidStateType.Jumping)
zomHum.MoveToFinished:Wait()
else
zomHum:MoveTo(waypoints[i].Position)
zomHum.MoveToFinished:Wait()
end
end
end
repeat
findPlayerWithSmell()
task.wait(1)
until nil
Here is the GameHandlerScript (No, I have not made a model for a second, third, or fourth zombie, so they do not exist. I commented them out in my actual script.)
zombieWorkspace = game.Workspace:FindFirstChild("ZombieWorkspace")
zombieInstances = game.ReplicatedStorage:FindFirstChild("Folder4Mobs")
zombieBossFolder = zombieInstances:FindFirstChild("Boss Folder")
zombieZombieFolder = zombieInstances:FindFirstChild("Zombie Folder")
allZombieSpawns = game.Workspace:FindFirstChild("Spawns"):FindFirstChild("Zombie"):GetChildren()
allPlayerSpawns = game.Workspace:FindFirstChild("Spawns"):FindFirstChild("Player"):GetChildren()
zombie1 = zombieZombieFolder:FindFirstChild("Zombie1")
zombie2 = zombieZombieFolder:FindFirstChild("Zombie2")
zombie3 = zombieZombieFolder:FindFirstChild("Zombie3")
zombie4 = zombieZombieFolder:FindFirstChild("Zombie4")
boss1 = zombieBossFolder:FindFirstChild("Boss")
roundNumber = game.ReplicatedStorage.GlobalStuff.RoundWaveNumber
timerNumber = game.ReplicatedStorage.GlobalStuff.TimerNumber
zombieAliveNumber = game.ReplicatedStorage.GlobalStuff.ZombiesAliveNumber
totalZombieNumber = game.ReplicatedStorage.GlobalStuff.TotalZombieNumber
playerAliveNumber = game.ReplicatedStorage.GlobalStuff.PlayersAliveNumber
teams = game:GetService("Teams")
function roundSystem()
zombiesToSpawn = math.ceil(4*(1.1^roundNumber.Value))
task.wait(2)
totalZombieNumber.Value = zombiesToSpawn
zombieAliveNumber.Value = zombiesToSpawn
plr = game.Players:GetPlayers()
for i = 1, #plr do
plr[i].Team = teams.Alive
playerAliveNumber.Value += 1
game.Workspace:FindFirstChild(plr[i].Name).HumanoidRootPart.Position = allPlayerSpawns[math.random(1,#allPlayerSpawns)].Position
end
if roundNumber.Value >= 1 and roundNumber.Value <= 5 then
for i = 1, zombiesToSpawn do
chance = math.random(1,100)
if chance >= 1 and chance <= 95 then
local zombie1Clone = zombie1:Clone()
randomZombieSpawn = allZombieSpawns[math.random(1, #allZombieSpawns)]
zombie1Clone.HumanoidRootPart.Position = randomZombieSpawn.Position + Vector3.new(0,3,0)
zombie1Clone.Parent = zombieWorkspace
elseif chance >= 96 and chance <= 100 then
local zombie2Clone = zombie2:Clone()
randomZombieSpawn = allZombieSpawns[math.random(1, #allZombieSpawns)]
zombie2Clone.HumanoidRootPart.Position = randomZombieSpawn.Position + Vector3.new(0,3,0)
zombie2Clone.Parent = zombieWorkspace
end
end
elseif roundNumber.Value >= 6 and roundNumber.Value <= 10 then
for i = 1, zombiesToSpawn do
chance = math.random(1,100)
if chance >= 1 and chance <= 60 then
local zombie1Clone = zombie1:Clone()
randomZombieSpawn = allZombieSpawns[math.random(1, #allZombieSpawns)]
zombie1Clone.HumanoidRootPart.Position = randomZombieSpawn.Position + Vector3.new(0,3,0)
zombie1Clone.Parent = zombieWorkspace
elseif chance >= 61 and chance <= 100 then
local zombie2Clone = zombie2:Clone()
randomZombieSpawn = allZombieSpawns[math.random(1, #allZombieSpawns)]
zombie2Clone.HumanoidRootPart.Position = randomZombieSpawn.Position + Vector3.new(0,3,0)
zombie2Clone.Parent = zombieWorkspace
end
end
if roundNumber.Value == 10 then
local boss1Clone = boss1:Clone()
randomZombieSpawn = allZombieSpawns[math.random(1, #allZombieSpawns)]
boss1Clone.HumanoidRootPart.Position = randomZombieSpawn.Position + Vector3.new(0,3,0)
boss1Clone.Parent = zombieWorkspace
end
elseif roundNumber.Value >= 11 and roundNumber.Value <= 15 then
for i = 1, zombiesToSpawn do
chance = math.random(1,100)
if chance >= 1 and chance <= 60 then
local zombie1Clone = zombie1:Clone()
randomZombieSpawn = allZombieSpawns[math.random(1, #allZombieSpawns)]
zombie1Clone.HumanoidRootPart.Position = randomZombieSpawn.Position + Vector3.new(0,3,0)
zombie1Clone.Parent = zombieWorkspace
elseif chance >= 61 and chance <= 100 then
local zombie2Clone = zombie2:Clone()
randomZombieSpawn = allZombieSpawns[math.random(1, #allZombieSpawns)]
zombie2Clone.HumanoidRootPart.Position = randomZombieSpawn.Position + Vector3.new(0,3,0)
zombie2Clone.Parent = zombieWorkspace
end
end
end
end
zombieWorkspace.ChildRemoved:Connect(function()
zombieAliveNumber.Value = #zombieWorkspace:GetChildren()
if zombieWorkspace:FindFirstChildWhichIsA("Model") == nil then
roundNumber += 1
zombiesToSpawn = math.ceil(4*(1.1^roundNumber))
roundSystem()
print(roundNumber)
end
end)
playerAliveNumber.Changed:Connect(function()
if playerAliveNumber.Value == 0 then
zombieWorkspace:ClearAllChildren()
roundNumber.Value = 1
roundSystem()
end
end)
roundSystem()