Two issues with my pathfinding module

Heya there.

I’m done implementing raycasting into a pathfinding module so enemies will ONLY pathfind if necessary. It works as intended as if a ray constantly being shot at their head detects a wall, pathfind. The issue however is that the enemy will ignore the player and head straight to the objective. After reaching the objective, it’ll then begin to chase after players after entering their AggroRange. Another issue arises however.

For some reason, even getting out of their range, they’ll still target you. Although this assumes the player is 30 or more studs away from the enemy when it spawns as 30 or more close to it will just do the latter problem. Any solutions?

--[[SERVICES]]--
local PathfindingService = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

--[[MODULE]]--
local PathfindingModule = {}

function PathfindingModule.Pathfind(NPC, AggroRange)
	--//Preperation
	local Objective = game.Workspace:FindFirstChild("Crystal")
	--Enemy
	local RootPart = NPC.PrimaryPart
	local Humanoid = NPC.Humanoid
	local CharacterSize = NPC:GetExtentsSize()

	RootPart:SetNetworkOwner(nil)

	--//Pathfinding Agents
	local PathfindingAgents = {
		AgentRadius = (CharacterSize.X + CharacterSize.Z)/4,
		AgentHeight = CharacterSize.Y,
		AgentCanJump = true
	}

	--[[PATHFINDING]]--
	local LookDirection = NPC.Head.CFrame.LookVector
	local function FollowPath(Destination)
		local RaycastingParams = RaycastParams.new()
		RaycastingParams.FilterDescendantsInstances = {NPC, Objective}
		RaycastingParams.FilterType = Enum.RaycastFilterType.Exclude
		
		local RaycastResult = workspace:Raycast(NPC.Head.Position, LookDirection * 30, RaycastingParams)
		if RaycastResult then
			--//That's bad, the enemy detected something in front of it (Besides players, other enemies, or the objective, a wall.)
			--//We can just pathfind it, however.
			local NewPath = PathfindingService:CreatePath(PathfindingAgents)
			NewPath:ComputeAsync(RootPart.Position,Destination)
			
			if NewPath.Status == Enum.PathStatus.Success then
				local Waypoints = NewPath:GetWaypoints()
				
				for _, Waypoint in pairs(Waypoints) do
					if Waypoint.Action == Enum.PathWaypointAction.Jump then
						Humanoid.Jump = true
					end
					
					--//Visualize
					local WaypointVisulize = Instance.new("Part",workspace)
					WaypointVisulize.Size = Vector3.new(1,1,1)
					WaypointVisulize.Anchored = true
					WaypointVisulize.CanCollide = false
					WaypointVisulize.Position = Waypoint.Position
					
					Humanoid:MoveTo(Waypoint.Position)
					local TimeOut = Humanoid.MoveToFinished:Wait(1)
					if not TimeOut then
						print("Path taking way too long. Recalculating.")
						Humanoid:MoveTo(Objective.PrimaryPart.Position)
					end
				end
			else
				print("Pathfinding went wrong, sorry.")
			end
		else
			--//That's good, enemy hasn't detected anything in front of it :3
			Humanoid:MoveTo(Objective.PrimaryPart.Position)
		end
		
		
		--[[
		--OLD
		local NewPath = PathfindingService:CreatePath(PathfindingAgents)
		NewPath:ComputeAsync(RootPart.Position, Destination)

		if NewPath.Status == Enum.PathStatus.Success then
			local Waypoints = NewPath:GetWaypoints()

			for _, Waypoint in ipairs(Waypoints) do

				if Waypoint.Action == Enum.PathWaypointAction.Jump then
					Humanoid.Jump = true
				end

				--Just in case
				NewPath.Blocked:Connect(function(blockedWaypointIdx)
					print("The enemy's path is blocked. Recalculating.")
					if Objective and Objective.PrimaryPart then
						FollowPath(Objective.PrimaryPart.Position)
					end
				end)

				Humanoid:MoveTo(Waypoint.Position)
				local Timer = Humanoid.MoveToFinished:Wait(1)
				if not Timer then
					print("Path timed out. Recalculating.")
					if Objective and Objective.PrimaryPart then
						FollowPath(Objective.PrimaryPart.Position)
					end
				end
			end
		else
			print("Path failed. Recalculating. Sorry.")
		end
		
		]]
	end

	local function FindNearestTarget()
		local NearestTarget = nil
		local PlayerList = Players:GetPlayers()

		for _, Player in pairs(PlayerList) do
			local Character = Player.Character or Player.CharacterAdded:Wait()

			if Character and Character.PrimaryPart then
				local Distance = (Character.PrimaryPart.Position - RootPart.Position).Magnitude
				if Distance <= AggroRange then
					NearestTarget = Character
				else
					NearestTarget = Objective
				end
			end
		end

		return NearestTarget
	end

	while task.wait(0.5) do
		local Target = FindNearestTarget()

		if Target and Target.PrimaryPart then
			--//Checking distance to be safe.
			local Distance = (Target.PrimaryPart.Position - RootPart.Position).Magnitude
			
			if Distance <= AggroRange then
				Objective = Target
			elseif not Target and Distance >= AggroRange then
				Objective = game.Workspace:FindFirstChild("Crystal")
			end
		else
			print("Character's RootPart cannot be found.")
		end

		if Objective and Objective.PrimaryPart then
			FollowPath(Objective.PrimaryPart.Position)
		end
	end
end

return PathfindingModule

Basically the code will keep yielding as the FollowPath function isn’t asynchronous meaning if the player enters the path then it would end up waiting until the current FollowPath is done before then go to the player. Wrapping it in a coroutine should fix it

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