NPCs only walk to the first waypoint of a path and then just stop moving entirely (bruh)

so basically i am making wandering, and on my last post i was told to use bindable events, BUT
i did NOT because i am a strong independent person that can fix all errors :sunglasses: (almost)

but right now, my enemies create a path, walk to the first waypoint of it and then just stop moving

this is the code…

module

function VisualizePath(waypoint: PathWaypoint)
	local pathVisualizer = Instance.new("Part")
	pathVisualizer.Shape = Enum.PartType.Ball
	pathVisualizer.Parent = workspace
	pathVisualizer.Position = waypoint.Position

	pathVisualizer.Color = Color3.fromRGB(255,255,255)
	pathVisualizer.Material = Enum.Material.Neon

	pathVisualizer.Size = Vector3.new(2,2,2)

	pathVisualizer.CanCollide = false
	pathVisualizer.Anchored = true

	dService:AddItem(pathVisualizer, 2)
end

function RandomWander(part: BasePart)
	local minBound = part.Position - part.Size / 2
	local maxBound = part.Position + part.Size / 2

	-- Calculate bounds;
	local minX = part.Position.X - part.Size.X / 2
	local maxX = part.Position.X + part.Size.X / 2
	local minZ = part.Position.Z - part.Size.Z / 2
	local maxZ = part.Position.Z + part.Size.Z / 2

	-- Randomize positions;
	local randomX = math.random() * (maxX - minX) + minX
	local randomZ = math.random() * (maxZ - minZ) + minZ

	local fixedY = part.Position.Y

	return Vector3.new(randomX, fixedY, randomZ)
end

function CreatePath(startPos: Vector3, targetPos: Vector3)
	local path: Path = pfService:CreatePath(pathParameters)

	local success, result = pcall(function()
		path:ComputeAsync(startPos, targetPos)
	end)

	if not success then
		warn("Pathfinding failed: " .. result)
		return
	end

	local waypoints = path:GetWaypoints()

	if path.Status == Enum.PathStatus.Success and #waypoints > 0 then
		print(waypoints)
		return waypoints
	end
end

function MoveTo(waypoints, humanoid: Humanoid)
	if waypoints == nil or #waypoints == 0 then
		warn("No waypoints!")
		return
	end

	for i = 1, #waypoints do
		local waypoint: PathWaypoint = waypoints[i]

		if waypoint.Action == Enum.PathWaypointAction.Jump then
			humanoid.Jump = true
		end

		VisualizePath(waypoint)

		humanoid:MoveTo(waypoint.Position)
		humanoid.MoveToFinished:Wait()
		print("erm, what the sigma?")
	end
end


-- Runtime;

local pathfinding = {}

function pathfinding.Wander(humanoid: Humanoid) -- Generates a random position and pathfinds to it (if player is not in LoS)
	local char: Model = humanoid.Parent
	local humanoidRootPart: BasePart = char:FindFirstChild("HumanoidRootPart")
	local detectionPart: BasePart = char:FindFirstChild("DetectionPart") 

	local startPos = humanoidRootPart.Position
	local targetPos = RandomWander(detectionPart)

	char:SetAttribute("Wandering", true)

	local waypoints = CreatePath(startPos, targetPos)

	if not waypoints then
		warn("No waypoints!")
		char:SetAttribute("Wandering", false)
		return
	end

	humanoid.WalkSpeed = enemyStats[char.Name]["WANDER_SPEED"]


	MoveTo(waypoints, humanoid)

	local cooldown = math.random(5,10)
	char:SetAttribute("Wandering", false)

	char:SetAttribute("WanderCooldown", true)
	task.wait(cooldown)
	char:SetAttribute("WanderCooldown", false)
	print("okay we set cooldown to false here we go!")
end

script where i call everything

local pathfindingModule = require(game:GetService("ServerScriptService"):WaitForChild("Enemies").PathfindingModule)

local runService = game:GetService("RunService")
local enemiesFolder = workspace:WaitForChild("Enemies")

while task.wait(0.05) do
	if #enemiesFolder:GetChildren() > 0 then
		local enemies = enemiesFolder:GetChildren()

		for _, enemy in ipairs(enemies) do
			if enemy.EnemyType.Value == "MELEE" then
				local detectionBox = enemy:FindFirstChild("DetectionPart")
				local humanoid = enemy:FindFirstChildOfClass("Humanoid")


				local closestPlayer = nil
				local LOS = workspace:GetPartBoundsInBox(detectionBox.CFrame, detectionBox.Size)

				for _, v in pairs(LOS) do
					if v.Parent:FindFirstChild("Humanoid") then
						local targetPlayer = game.Players:GetPlayerFromCharacter(v.Parent)

						if targetPlayer then
							if closestPlayer == nil or (enemy.HumanoidRootPart.Position - targetPlayer.Character.HumanoidRootPart.Position).Magnitude < (enemy.HumanoidRootPart.Position - closestPlayer.Character.HumanoidRootPart.Position).Magnitude then
								closestPlayer = targetPlayer
							end
						end
					end
				end

				task.spawn(function()
					if closestPlayer then
						local targetPosition = closestPlayer.Character.Torso.PathfindPart.Position
						pathfindingModule.Chase(humanoid, targetPosition) -- this is irrelevant
						enemy:SetAttribute("Chasing", true)
					else
						if enemy:GetAttribute("WanderCooldown") == false and enemy:GetAttribute("Wandering") == false then
							pathfindingModule.Wander(humanoid)
						else
							humanoid:MoveTo(humanoid.Parent.HumanoidRootPart.Position)
						end
					end
				end)
			end
		end
	end
end
1 Like

this remains… [UNSOLVED]!!!

bumping this will get me flagged, buuut, winning requires sacrifice!

1 Like

okay, i have a theory as to why they only move to th efirst waypoint, but i’m probably horribly wrong

gonna comment everything;

local pathfindingModule = require(game:GetService("ServerScriptService"):WaitForChild("Enemies").PathfindingModule)

local runService = game:GetService("RunService")
local enemiesFolder = workspace:WaitForChild("Enemies")

while task.wait(0.05) do -- runs every 0.5 secs
	if #enemiesFolder:GetChildren() > 0 then
		local enemies = enemiesFolder:GetChildren()

		for _, enemy in ipairs(enemies) do
			if enemy.EnemyType.Value == "MELEE" then
				local detectionBox = enemy:FindFirstChild("DetectionPart")
				local humanoid = enemy:FindFirstChildOfClass("Humanoid")


				local closestPlayer = nil
				local LOS = workspace:GetPartBoundsInBox(detectionBox.CFrame, detectionBox.Size)

				for _, v in pairs(LOS) do
					if v.Parent:FindFirstChild("Humanoid") then
						local targetPlayer = game.Players:GetPlayerFromCharacter(v.Parent)

						if targetPlayer then
							if closestPlayer == nil or (enemy.HumanoidRootPart.Position - targetPlayer.Character.HumanoidRootPart.Position).Magnitude < (enemy.HumanoidRootPart.Position - closestPlayer.Character.HumanoidRootPart.Position).Magnitude then
								closestPlayer = targetPlayer
							end
						end
					end
				end

				task.spawn(function() -- this makes a new function
					if closestPlayer then
						local targetPosition = closestPlayer.Character.Torso.PathfindPart.Position
						pathfindingModule.Chase(humanoid, targetPosition)
						enemy:SetAttribute("Chasing", true)
					else
						if enemy:GetAttribute("WanderCooldown") == false and enemy:GetAttribute("Wandering") == false then
							pathfindingModule.Wander(humanoid) -- this will work, but since it only gets called if enemy isn't wandering, and the cooldown is down, there is only so much it can do
						else
							humanoid:MoveTo(humanoid.Parent.HumanoidRootPart.Position) -- once 0.5 seconds have passed, the code will create yet another function, but since wandering requirements are not met, it will instead stop (or move to the rootpart position)
						end
					end
				end)
			end
		end
	end
end

my theory… was correct!!!

charrrrrrrr

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.