Zombie pathfinding

  1. What do you want to achieve? I want to make it so that the zombie initially goes to the desk, but if the attackValue changes to true, then the zombie would go to the player

  2. What is the issue? I need the zombie to follow the player after the Attack Player has changed.Value to true, and in other cases went to the part

  3. What solutions have you tried so far? I checked other roblox forums

Attack Player located in zombie.Configs as IntValue
I used a translator, so there may be mistakes in my text, ask questions if you need

local PathfindingService = game:GetService("PathfindingService")
local hum = script.Parent:WaitForChild("Humanoid")
local torso = script.Parent:WaitForChild("Torso")
local path
local target

function findTarget()
	local result
	local GetPart

	if script.Parent.Configs.AttackPlayer.Value then
		for i,v in pairs(workspace:GetChildren()) do
			if v:FindFirstChildOfClass("Humanoid") then
				GetPart = v.PrimaryPart
			end
		end
	else
		GetPart = workspace.Map.Truck.PrimaryPart
	end

	return GetPart
end

while task.wait(0.1) do
	target = findTarget()
	
	if target ~= nil then
		path = PathfindingService:CreatePath()
		path:ComputeAsync(torso.Position, target.Position)
		local waypoints = path:GetWaypoints()

		for i,v in pairs(waypoints) do
			hum:MoveTo(v.Position)

			if v.Action == Enum.PathWaypointAction.Jump then
				hum:ChangeState(Enum.HumanoidStateType.Jumping)
			end

			hum.MoveToFinished:Wait()
		end
	end
end
2 Likes

You can just attach a function to the :PropertyChangedSignal and do whatever you need to do there. I don’t see why Attack Player needs to be an IntValue though, if anything it should be a stringValue but I don’t know your project structure. Please correct me if I misunderstood your problem.

3 Likes

Oh yes, I wrote it wrong, I have a boolvalue, I would try your option, but the problem is that the zombie waits until it completes the movement to a certain point, and the player can attack at any moment. Either I didn’t quite understand you either, correct me if that’s not the case.

2 Likes

Thanks for the help, but unfortunately in my case, a zombie always knows where to go, so far I have problems with how to redirect zombies from the part to the player

3 Likes

It’s because of the function inside the while loop

hum.MoveToFinished:Wait()

put an else there and then place

for i,v in pairs(waypoints) do
			hum:MoveTo(v.Position)

			if v.Action == Enum.PathWaypointAction.Jump then
				hum:ChangeState(Enum.HumanoidStateType.Jumping)
			end

			hum.MoveToFinished:Wait()
		end
1 Like

Can you explaint please, else for what? I have only one if, and its just checking target

2 Likes

Forgot to add

if target == nil then
		path = PathfindingService:CreatePath()
		path:ComputeAsync(torso.Position, target.Position)
		local waypoints = path:GetWaypoints()

		for i,v in pairs(waypoints) do
			hum:MoveTo(v.Position)

			if v.Action == Enum.PathWaypointAction.Jump then
				hum:ChangeState(Enum.HumanoidStateType.Jumping)
			end

			hum.MoveToFinished:Wait()
		end
else
findTarget()
	end
2 Likes

It didnt help :frowning: , zombie stopped attacking

2 Likes
local Model = script.Parent
local Humanoid = Model.Humanoid
local PSS = game:GetService("PathfindingService")
local Path = PSS:CreatePath()
local Values = script.Parent.Configs
local blockedConnection
local nextWaypointIndex = 1
local reachedConnection
--game.Workspace.Map1.Truck.PrimaryPart = game.Workspace.Map1.Truck.Part
local function seeTarget(Target)
	local origin = Model.PrimaryPart.Position
	local direction = (Target.PrimaryPart.Position - Model.PrimaryPart.Position).unit * 90
	local ray = Ray.new(origin, direction)
	
local hit, pos = workspace:FindPartOnRay(ray, Model)
	
	if hit then
		if hit:IsDescendantOf(Target) then
			return true
		end--
	else
	return false	
end--
end
local function targetFind()
	local Players = game.Players:GetPlayers()
	local MaxDistance = 250 -- use any
	local GetPart 
	local firstTarget
	for i, plr in pairs(Players) do
		if plr.Character then
			local Target = plr.Character
			local Distance = (Model.PrimaryPart.Position - Target.PrimaryPart.Position).Magnitude
			if Distance < MaxDistance then 
				firstTarget = 	Target
				print(Target.Name)
				MaxDistance = Distance
			end
		end
	end
	return firstTarget
end
local function getPath(destination)
	local PathTable = {
		AgentHeight = 2,
		AgentRadius = 1,
		AgentCanJump = true,
		AgentCanClimb = true,
		Costs = {
			Jump = 1,
			Climb = 1,
			Danger = math.huge
		}
}
	local Path = PSS:CreatePath(PathTable)
	
	Path:ComputeAsync(Model.HumanoidRootPart.Position, destination)
	return Path
	
end
local function pathGet(Destination)
	local target = targetFind()
	local PathTable2 = {
		AgentHeight = 2,
		AgentRadius = 1,
		AgentCanJump = true,
		AgentCanClimb = true,
		Costs = {
			Jump = 1,
			Climb = 1,
			Danger = math.huge
		}
	}

	local Path2 = PSS:CreatePath(PathTable2)
	Path2:ComputeAsync(Model.PrimaryPart.Position - Vector3.new(0, Model.PrimaryPart.Size.Y/0.75, 0), target.PrimaryPart.Position)
	
	if PathWaypoint.Action == Enum.PathWaypointAction.Jump then
		Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
	end
	
return Path2
end


local function atk(Target, destination)
	local Distance = (Model.HumanoidRootPart.Position - Target.HumanoidRootPart.Position).Magnitude
	if Distance > 7 then
		local pathy = pathGet(destination)
		if pathy.Status == Enum.PathStatus.Success then
			for i, v in pairs (pathy:GetWaypoints()) do
				if v.Action == Enum.PathWaypointAction.Jump then
					Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
				end
				Humanoid:MoveTo(v.Position)
			end
			
		else
			print("Path Unsuccesful")
	end
		
	else	

		Model:MoveTo(Target.HumanoidRootPart.Position)
		Target.Humanoid.Health = 0
		Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		Humanoid:MoveTo(script.Parent.HumanoidRootPart.Position - (script.Parent.HumanoidRootPart.CFrame.LookVector * 100))
	end
end

local function moveTo(destination)
	local path = getPath(destination)
	if path.Status == Enum.PathStatus.Success then
		
		for i, v in pairs (path:GetWaypoints()) do
			
			if v.Action == Enum.PathWaypointAction.Jump then
				Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			end
			local Target = targetFind()
			if Target and Target.Humanoid.Health > 0 then
				print("Found", Target.Name,"now targeting")
				atk(Target)
				print(path.Status)
				Values.AttackPlayer.Value = true			
				break 
			else
				blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
					if blockedWaypointIndex >= nextWaypointIndex then
						-- Stop if there's a part
						blockedConnection:Disconnect()
						-- Re compute
						moveTo(destination)
					end
				end)

				print(path.Status)
				Values.AttackPlayer.Value = false
				print("No target.", "Moving to", v.Position)
				Humanoid:MoveTo(v.Position)
 					Humanoid.MoveToFinished:Wait()
			end
				end
	else
		print("Path Unsuccesful")
	--Humanoid:MoveTo(destination.Position - (Model.HumanoidRootPart.CFrame.LookVector * 15))
	end
		
		
end
local function Move()
	
	local path = game.Workspace.Map1:FindFirstChild("Truck").PrimaryPart
	local point = path.Position
	wait()
	moveTo(point)
end

while task.wait() do
	Move()
end

I used 2 pathfinding services here really

One for the chase and one for the “truck” that it’s going to. I would recommend you use random points. You shouldn’t just use one.

It worked for me so it should work for you; just try it in a new line

1 Like

As for “random” points I mean it like;

local function Move()
	local Waypoints = game.Workspace:FindFirstChild("Waypoints") -- make a folder like this and then insert your points here
	local Points = Waypoints:GetChildren()	
	local randompoint = math.random(1, #points)	
	wait()
	moveTo(points[randompoint])
end

while task.wait() do
	Move()
end
1 Like

Yes, it really works, but sometimes zombie using cheats and jump inf times

2 Likes
local function atk(Target, destination)
	local Value = Values.AttackPlayer.Value
if Value == true then
		local Distance = (Model.HumanoidRootPart.Position - Target.HumanoidRootPart.Position).Magnitude
		if Distance > 7 then
			local pathy = pathGet(destination)
			if pathy.Status == Enum.PathStatus.Success then
				for i, v in pairs (pathy:GetWaypoints()) do
					if v.Action == Enum.PathWaypointAction.Jump then
						Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
					end
					Humanoid:MoveTo(v.Position)
				end

			else
				print("Path Unsuccesful")
			end

		else	

			Model:MoveTo(Target.HumanoidRootPart.Position)
			Target.Humanoid.Health = 0
			HitSound:Play()
			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			Humanoid:MoveTo(script.Parent.HumanoidRootPart.Position - (script.Parent.HumanoidRootPart.CFrame.LookVector * 100))
		end
	else
		warn("Value not true")
	end
end

1 Like

Remove the jump detection on the function since it’s doing that

It’s already on another function so it loops through

1 Like

i think i have some bugs with it https://youtu.be/CTBjD-Gv8Mg

2 Likes

Oh yes, when it attacks I made it so it teleports to the player.

Just remove the

	Model:MoveTo(Target.HumanoidRootPart.Position)

on the attack local function atk(Target, destination) function and then change the Distance to 4

1 Like
local Model = script.Parent
local Humanoid = Model.Humanoid
local PSS = game:GetService("PathfindingService")
local Path = PSS:CreatePath()
local Values = script.Parent.Configs
local blockedConnection
local nextWaypointIndex = 1
local reachedConnection
--game.Workspace.Map1.Truck.PrimaryPart = game.Workspace.Map1.Truck.Part
local function seeTarget(Target)
	local origin = Model.PrimaryPart.Position
	local direction = (Target.PrimaryPart.Position - Model.PrimaryPart.Position).unit * 90
	local ray = Ray.new(origin, direction)

	local hit, pos = workspace:FindPartOnRay(ray, Model)

	if hit then
		if hit:IsDescendantOf(Target) then
			return true
		end--
	else
		return false	
	end--
end
local function targetFind()
	local Players = game.Players:GetPlayers()
	local MaxDistance = 50 -- use any
	local GetPart 
	local firstTarget
	for i, plr in pairs(Players) do
		if plr.Character then
			local Target = plr.Character
			local Distance = (Model.PrimaryPart.Position - Target.PrimaryPart.Position).Magnitude
			if Distance < MaxDistance then 
				firstTarget = 	Target
				print(Target.Name)
				MaxDistance = Distance
			end
		end
	end
	return firstTarget
end
local function getPath(destination)
	local PathTable = {
		AgentHeight = 2,
		AgentRadius = 1,
		AgentCanJump = true,
		AgentCanClimb = true,
		Costs = {
			Jump = 1,
			Climb = 1,
			Danger = math.huge
		}
	}
	local Path = PSS:CreatePath(PathTable)

	Path:ComputeAsync(Model.HumanoidRootPart.Position, destination)
	return Path

end
local function pathGet(Destination)
	local target = targetFind()
	local PathTable2 = {
		AgentHeight = 2,
		AgentRadius = 1,
		AgentCanJump = true,
		AgentCanClimb = true,
		Costs = {
			Jump = 1,
			Climb = 1,
			Danger = math.huge
		}
	}

	local Path2 = PSS:CreatePath(PathTable2)
	Path2:ComputeAsync(Model.PrimaryPart.Position - Vector3.new(0, Model.PrimaryPart.Size.Y/0.75, 0), target.PrimaryPart.Position)

	--if PathWaypoint.Action == Enum.PathWaypointAction.Jump then
	--	Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
	--end

	return Path2
end

local function atk(Target, destination)
	local Value = Values.AttackPlayer.Value
	if Value == true then
		local Distance = (Model.HumanoidRootPart.Position - Target.HumanoidRootPart.Position).Magnitude
		if Distance > 4 then
			local pathy = pathGet(destination)
			if pathy.Status == Enum.PathStatus.Success then
				for i, v in pairs (pathy:GetWaypoints()) do
					if v.Action == Enum.PathWaypointAction.Jump then
						Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
					end
					Humanoid:MoveTo(v.Position)
				end

			else
				print("Path Unsuccesful")
			end

		else	

			Target.Humanoid.Health -= 15
			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			Humanoid:MoveTo(script.Parent.HumanoidRootPart.Position - (script.Parent.HumanoidRootPart.CFrame.LookVector * 100))
		end
	else
		warn("Value not true")
	end
end

local function moveTo(destination)
	local path = getPath(destination)
	if path.Status == Enum.PathStatus.Success then

		for i, v in pairs (path:GetWaypoints()) do

			if v.Action == Enum.PathWaypointAction.Jump then
				Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			end
			local Target = targetFind()
			if Target and Target.Humanoid.Health > 0 then
				print("Found", Target.Name,"now targeting")
				atk(Target)
				print(path.Status)
				Values.AttackPlayer.Value = true			
				break 
			else
				blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
					if blockedWaypointIndex >= nextWaypointIndex then
						-- Stop if there's a part
						blockedConnection:Disconnect()
						-- Re compute
						moveTo(destination)
					end
				end)

				print(path.Status)
				Values.AttackPlayer.Value = false
				print("No target.", "Moving to", v.Position)
				Humanoid:MoveTo(v.Position)
				Humanoid.MoveToFinished:Wait()
			end
		end
	else
		print("Path Unsuccesful")
		--Humanoid:MoveTo(destination.Position - (Model.HumanoidRootPart.CFrame.LookVector * 15))
	end


end
local function Move()

	local path = game.Workspace.Map:FindFirstChild("Truck").PrimaryPart
	local point = path.Position
	wait()
	print(point)
	moveTo(point)
end

while task.wait() do
	Move()
end

he is still jumping, maybe this can help you, or maybe i did something wrong

2 Likes

You didn’t remove it

local function atk(Target, destination)
	local Value = Values.AttackPlayer.Value
	if Value == true then
		local Distance = (Model.HumanoidRootPart.Position - Target.HumanoidRootPart.Position).Magnitude
		if Distance > 4 then
			local pathy = pathGet(destination)
			if pathy.Status == Enum.PathStatus.Success then
* for i, v in pairs (pathy:GetWaypoints()) do *
* if v.Action == Enum.PathWaypointAction.Jump then --remove these
*Humanoid:ChangeState(Enum.HumanoidStateType.Jumping) *
					end
					Humanoid:MoveTo(v.Position)
				end

			else
				print("Path Unsuccesful")
			end

		else	

			Target.Humanoid.Health -= 15
			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			Humanoid:MoveTo(script.Parent.HumanoidRootPart.Position - (script.Parent.HumanoidRootPart.CFrame.LookVector * 100))
		end
	else
		warn("Value not true")
	end
end


I see you removed the other one too, maybe that’s why. Another solution is you can just turn the true into false on the pathGet() value

1 Like

i think i dont understanding something, i deleted strings in * *, but in Humanoid:MoveTo(v.Position) v isnt defined
For now i have this one

	local Value = Values.AttackPlayer.Value
	if Value == true then
		local Distance = (Model.HumanoidRootPart.Position - Target.HumanoidRootPart.Position).Magnitude
		if Distance > 4 then
			local pathy = pathGet(destination)
			if pathy.Status == Enum.PathStatus.Success then
				Humanoid:MoveTo(v.Position)
			else
				print("Path Unsuccesful")
			end

		else	

			Target.Humanoid.Health -= 15
			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			Humanoid:MoveTo(script.Parent.HumanoidRootPart.Position - (script.Parent.HumanoidRootPart.CFrame.LookVector * 100))
		end
	else
		warn("Value not true")
	end
end

but v still not defined

1 Like

My fault, you were just supposed to remove the

 if v.Action == Enum.PathWaypointAction.Jump then 
*Humanoid:ChangeState(Enum.HumanoidStateType.Jumping) *
					end

It should look like this at the end;

local function atk(Target, destination)
	local Value = Values.AttackPlayer.Value
	if Value == true then
		local Distance = (Model.HumanoidRootPart.Position - Target.HumanoidRootPart.Position).Magnitude
		if Distance > 4 then
			local pathy = pathGet(destination)
			if pathy.Status == Enum.PathStatus.Success then
*for i, v in pairs (pathy:GetWaypoints()) do 

					Humanoid:MoveTo(v.Position)
				end

			else
				print("Path Unsuccesful")
			end

		else	

			Target.Humanoid.Health -= 15
			Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
			Humanoid:MoveTo(script.Parent.HumanoidRootPart.Position - (script.Parent.HumanoidRootPart.CFrame.LookVector * 100))
		end
	else
		warn("Value not true")
	end
end
1 Like

yea, it works but zombie cant attack truck and still jumping but in another way

2 Likes