Navigation seems extremely... off

  1. What do you want to achieve? I’m currently building a stratagy game, and I want NPC’s to automatically approach a central objective if there is not an enemy within range.

  2. What is the issue? The units, even though they can jump, get stuck on balconies, they randomly switch direcitons away from the battle and ram themselves into more ledges, and they just don’t acknowledge that the objective exists. I don’t see what could be causing them to go the opposite direction of any destinations

  3. What solutions have you tried so far? I’ve disabled the destination = Humanoid.PrimaryPart.Position code, because I thought that the position was messed up somehow, and I’ve tried looking through the Developer Forums, and couldn’t find an answer. Probably because of how specific this problem is.
    demo of problem:
    (bruh - YouTube)
    my code (prob terrible)

local PathfindingService = game:GetService("PathfindingService")
local sstorage = game:GetService("ServerStorage")
local scanfuncs = require(sstorage:WaitForChild("Scan"))
local path = PathfindingService:CreatePath({
	AgentRadius = 3,
	AgentHeight = 6,
	AgentCanJump = true,
	Costs = {
		Water = 20
	}
})
local reachedConnection
local blockedConnection
function GetDescendantsOfClass(Parent, Type)
	local Table = {}

	for _, Object in ipairs(Parent:GetDescendants()) do
		if Object:IsA(Type) then
			table.insert(Table, Object)
		end
	end

	return Table
end
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local team = script.Parent:GetAttribute("team")
local mindistance = 4
local reactiontime = 0.2
local range = 150
local objective = workspace.Objectives:FindFirstChild("CP")
local tickssincelastfire = 0
local Humanoid = script.Parent
local AttackEvent = Humanoid.Parent:WaitForChild("Attack")
local perms = RaycastParams.new()
perms.FilterType = Enum.RaycastFilterType.Blacklist
local enemyteamfolder;
local head = Humanoid.Parent:WaitForChild("Head")
local runservice = game:GetService("RunService")
if (team=="red") then
	enemyteamfolder = workspace.Units:WaitForChild("BlueUnits")
	teamfolder = workspace.Units:WaitForChild("RedUnits")
else
	enemyteamfolder = workspace.Units:WaitForChild("RedUnits")
	teamfolder = workspace.Units:WaitForChild("BlueUnits")
end
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local character = Humanoid.Parent
local destination = Humanoid.Parent.PrimaryPart.Position
local lastdest = character.PrimaryPart.Position
while(true) do
	local closest = scanfuncs.scan(teamfolder, enemyte
amfolder, head.Position, range, mindistance) --Scanfuncs just looks for enemies within range
	if closest then
		if (closest.PrimaryPart.Position - head.Position).Magnitude < 5 then
			AttackEvent:Fire()
		else
			destination = closest.PrimaryPart.Position
		end
	else if (character.PrimaryPart.Position - objective.Position).Magnitude > 10 then
			destination = objective.Position
		else
			destination = objective.Position
		end
	end
	if destination ~= lastdest then
		local success, errorMessage = pcall(function()
			if(character) then
				path:ComputeAsync(character.PrimaryPart.Position, destination)
			end
		end)

		if success and path.Status == Enum.PathStatus.Success then
			-- Get the path waypoints
			waypoints = path:GetWaypoints()

			-- Detect if path becomes blocked
			blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
				-- Check if the obstacle is further down the path
				if blockedWaypointIndex >= nextWaypointIndex then
					-- Stop detecting path blockage until path is re-computed
					blockedConnection:Disconnect()
					-- Call function to re-compute new path
					--followPath(destination)
				end
			end)
		-- Detect when movement to next waypoint is complete
		if not reachedConnection then
			reachedConnection = Humanoid.MoveToFinished:Connect(function(reached)
				if reached and nextWaypointIndex < #waypoints then
					-- Increase waypoint index and move to next waypoint
					nextWaypointIndex += 1
					if waypoints[nextWaypointIndex-1].Action == Enum.PathWaypointAction.Jump then
						Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
						print('jumping')
					end
					Humanoid:MoveTo(waypoints[nextWaypointIndex].Position) 
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end

		-- Initially move to second waypoint (first waypoint is path start; skip it)
		nextWaypointIndex = 2
		Humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	else
		if not reachedConnection then
			reachedConnection = Humanoid.MoveToFinished:Connect(function(reached)
				if reached and nextWaypointIndex < #waypoints then
					-- Increase waypoint index and move to next waypoint
					nextWaypointIndex += 1
					if waypoints[nextWaypointIndex-1].Action == Enum.PathWaypointAction.Jump then
						Humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
						print('jumping')
					end
					Humanoid:MoveTo(waypoints[nextWaypointIndex].Position) 
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
				
		end
		lastdest = destination
		wait(reactiontime)
		end
	end
end