Zombie will not kill me. Nice. Wait, Wrong!

My zombie AI is not working. I checked a bunch of stuff with prints and there were no errors. The main problem is the zombie simply stands there and not move. Again, there are no errors. Here is my script. (It used to work)

local zombie = script.Parent
local humanoid = zombie.Humanoid
zombie.PrimaryPart:SetNetworkOwner(nil)

--repeat wait() until script.Parent.Sounds:FindFirstChildWhichIsA("Folder")

local function canSeeTarget(target)
	local origin = zombie.HumanoidRootPart.Position
	local direction = (target.HumanoidRootPart.Position - zombie.HumanoidRootPart.Position).unit * 80
	local ray = Ray.new(origin, direction)
	
	local hit, pos = workspace:FindPartOnRay(ray, zombie)
	
	
	if hit then
		if hit:IsDescendantOf(target) then
			return true
		end
	else
		return false
	end
end

local function findTarget()
	local players = game.Players:GetPlayers()
	local maxDistance = 80
	local nearestTarget
	
	for index, player in pairs(players) do
		if player.Character then
			local target = player.Character
			local distance = (zombie.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude
			
			if distance < maxDistance and canSeeTarget(target) then
				nearestTarget = target
				maxDistance = distance
			end
		end
	end
	
	return nearestTarget
end

local function getPath(destination)
	local PathfindingService = game:GetService("PathfindingService")
	
	local pathParams = {
		["AgentHeight"] = 5,
		["AgentRadius"] = 3,
		["AgentCanJump"] = true
	}
	
	local path = PathfindingService:CreatePath(pathParams)
	
	path:ComputeAsync(zombie.HumanoidRootPart.Position, destination.Position)
	
	return path
end

local function attack(target)
	local distance = (zombie.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude

	if distance > 6 then
		humanoid:MoveTo(target.HumanoidRootPart.Position)
		if math.random(1, 50) == 1 then
			script.Parent.Sounds.Chasing:FindFirstChild("Sound" .. tostring(math.random(1, #script.Parent.Sounds.Walking:GetChildren()))):Play()
			wait(1)
		end
		--	humanoid.MoveToFinished:Wait()
	else
		--stop movement
		zombie.Humanoid.WalkSpeed = 0
		--target.Humanoid.WalkSpeed = 0
		-- play sound
	--	zombie.Head.AttackSound:Play()
		--fire event
		--local playerDeath = game.ReplicatedStorage:WaitForChild("playerDeath")
		local player = game.Players:GetPlayerFromCharacter(target)
	--	playerDeath:FireClient(player, zombie)
		-- play the animation
	--	local attackAnim = humanoid:LoadAnimation(script.AttackAnim)
	--	attackAnim:Play()
	--	attackAnim.Stopped:Wait()
		-- kill the player
		if player and target.Name ~= "Zombie" then
			target.Humanoid.Health -= 10
			script.Parent.Sounds.Attacking:FindFirstChild("Sound" .. tostring(math.random(1, #script.Parent.Sounds.Walking:GetChildren()))):Play()

			--restart movement
			zombie.Humanoid.WalkSpeed = 16
			wait(1)
		end
	end
end

local function displayPath(waypoints)
	local color = BrickColor.Random()
	for index, waypoint in pairs(waypoints) do
		local part = Instance.new("Part")
		part.BrickColor = color
		part.Anchored = true
		part.CanCollide = false
		part.Size = Vector3.new(1,1,1)
		part.Position = waypoint.Position
		part.Parent = workspace
		local Debris = game:GetService("Debris")
		Debris:AddItem(part, 6)
	end
end

local function walkTo(destination)
	
	local path = getPath(destination)
	print("got path")
	if path.Status == Enum.PathStatus.Success then
		displayPath(path:GetWaypoints())
		for index, waypoint in pairs(path:GetWaypoints()) do
			local target = findTarget()
			if target and target.Humanoid.Health > 0 then
				attack(target)
				break
			else
				print("Moving to ", waypoint.Position)
				humanoid:MoveTo(waypoint.Position)
				humanoid.MoveToFinished:Wait()
			end
		end
	else
		print("NO way!")
		humanoid:MoveTo(destination.Position - (zombie.HumanoidRootPart.CFrame.LookVector * 10))
	end
end

function patrol()
	local patrolPoints = game.Workspace:WaitForChild("CurrentMap"):WaitForChild("Patrol")	
	local waypoints = patrolPoints:GetChildren()
	if waypoints then	
		local randomNum = math.random(1, #waypoints)
		print(waypoints[randomNum])
		walkTo(waypoints[randomNum])
	else
		warn("No Waypoints...")
		print("Walking to...a patroal point", waypoints, #waypoints)
	end
end

while wait(0.25) do
	patrol()
	if math.random(1, 75) == 1 then
		script.Parent.Sounds.Walking:FindFirstChild("Sound" .. tostring(math.random(1, #script.Parent.Sounds.Walking:GetChildren()))):Play()
	end
end



humanoid.Died:Connect(function()
	script.Parent.Sounds.Dying:FindFirstChild("Sound" .. tostring(math.random(1, #script.Parent.Sounds.Walking:GetChildren()))):Play()
	script.Parent.HitBox:Destroy()
	local gui = script.Parent.Head:FindFirstChildWhichIsA("BillboardGui")
	if gui then
		gui:Destroy()
	end
end)

Thanks in advance - Zombo

2 Likes

I ran the code with a test model from the toolbox and it was working fine for me. I think it’s possible your script could be yielding at

local patrolPoints = game.Workspace:WaitForChild("CurrentMap"):WaitForChild("Patrol")	

1 Like

I just did some random test and it seems your correct, the zombies work fine. However, every time the game map is cloned into the workspace, the zombies freeze, when the map is deleted, the zombie work fine. This is quite the conundrum.

1 Like

You should post the code you’re using to clone the map to the workspace as well as the explorer for the map. Maybe we can figure out a solution to this problem.

Here you go.

local maps = game:GetService("ReplicatedStorage"):WaitForChild("Maps"):GetChildren()
local chosenMap = maps[math.random(1, #maps)]:Clone()
	chosenMap.Parent = workspace

Could you also post the explorer for your maps?

2 Likes

image

image

So when you close your maps to the workspace, are you renaming them to CurrentMap

That is correct. I do indeed rename them.

So I think you can definitely modify the logic of your code to prevent the zombies from staying still when the map is being cloned in.

patrol() waits until it can find the map and the patrol points before even deciding to move the zombies, but you can definitely alter it to check if the map exists, if it does then continue as it should, otherwise it can check for the closet player and see if can target them. If it can, then move them towards the player. Otherwise, have them move to a random position nearby.

2 Likes