Pathfinding trying to walk through walls

So, I’m making a monster, and he keeps trying to walk through walls.

clip:

its not a problem with it not trying. it is. but it just thinks it can Path find through the wall.
also if there is anything else I could approve pleas tell me
code:

-- settings --
local ViewDistance = 30
local ChaseSpeed = 18
local WalkSpeed = 9

local Attacks = {
	Close = {
		Swing = function()
			print("ok")
		end,
	}
}

-------------------------
-------------------------

local Character = script.Parent
local Humanoid = Character.Humanoid
local RootPart = Humanoid.RootPart
local XOffset = Character.UpperTorso.Neck.C0.X
local YOffset = Character.UpperTorso.Neck.C0.Y
local ZOffset = Character.UpperTorso.Neck.C0.Z
local Values = script.Parent.Values

local PathfindingService = game:GetService("PathfindingService")
local TweenService = game:GetService("TweenService")

local can = false
local MAX_RETRIES = 5
local RETRY_COOLDOWN = 5
local YIELDING = false
local Agentparams = {
	AgentRadius = 5,
	AgentHeight = 10,
	AgentCanClimb = false,
	AgentCanJump = false,
	WaypointSpacing = 1,
	Costs = {
		Water = 100,
		DangerZone = math.huge
	}
}


local path = PathfindingService:CreatePath(Agentparams)

local reachedConnection
local pathBlockedConnection
local moveto
local target
local lastseenpos


function Stare(Hrp,Stop)
	if Stop == true then
		Character.Torso.Neck.C0 = CFrame.new(XOffset, YOffset, ZOffset)
		return
	end
	local dist = (Hrp.Position - RootPart.Position).Magnitude
	local dir = (Hrp.Position - RootPart.Position).Unit
	local vecA = Vector2.new(RootPart.CFrame.LookVector.X, RootPart.CFrame.LookVector.Z)
	local vecB = Vector2.new(dir.X, dir.Z)
	local dotValue = vecA:Dot(vecB)
	local crossValue = vecA:Cross(vecB)
	local ht = RootPart.Position.Y - Hrp.Position.Y
	local upAngle = math.atan(ht/dist)

	local angle = math.atan2(crossValue, dotValue)
	if angle > math.pi/3 then
		angle = math.pi/3
	elseif angle < -math.pi/3 then
		angle = -math.pi/3
	end
	TweenService:Create(Character.UpperTorso.Neck,TweenInfo.new(.05),{C0 = CFrame.new(XOffset, YOffset, ZOffset) * CFrame.Angles(0, -angle + 160, 0) * CFrame.Angles(-upAngle + 50, 0, 0)}):Play()
end

local function WalkTo(Pos, yieldable)
	local RETRY_NUM = 0
	local success, errorMessage
	
	repeat
		RETRY_NUM += 1
		success, errorMessage = pcall(path.ComputeAsync, path, RootPart.Position, Pos)
		if not success then
			warn("Pathfind compute path error: "..errorMessage)
			task.wait(RETRY_COOLDOWN)
		end
	until success == true or RETRY_NUM > MAX_RETRIES

	if success then
		if path.Status == Enum.PathStatus.Success then
			local waypoints = path:GetWaypoints()
			local currentWaypointIndex = 2
			
			if not reachedConnection then
				reachedConnection = Humanoid.MoveToFinished:Connect(function(reached)
					if reached and currentWaypointIndex < #waypoints then
						currentWaypointIndex += 1
						Humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
						if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
							Humanoid.Jump = true
						end
					else
						
						reachedConnection:Disconnect()
						pathBlockedConnection:Disconnect()
						reachedConnection = nil
						pathBlockedConnection = nil
						YIELDING = false
					end
				end)
			end

			pathBlockedConnection = path.Blocked:Connect(function(waypointNumber)
				if waypointNumber > currentWaypointIndex then
					if reachedConnection then
						reachedConnection:Disconnect()
					end
					if pathBlockedConnection then
						pathBlockedConnection:Disconnect()
					end
					reachedConnection = nil
					pathBlockedConnection = nil
					WalkTo(Pos, true)
				end
			end)
			
			Humanoid:MoveTo(waypoints[currentWaypointIndex].Position)
			if waypoints[currentWaypointIndex].Action == Enum.PathWaypointAction.Jump then
				Humanoid.Jump = true
			end

			if yieldable then
				YIELDING = true
				repeat 
					task.wait()
				until YIELDING == false
			end
		else
			return 
		end
	else
		warn("Pathfind compute retry maxed out, error: "..errorMessage)
		return
	end

end

function GetDodge()
	local character1Position = Character.HumanoidRootPart.Position
	local character2Position = target.HumanoidRootPart.Position

	local positionDifference = character2Position - character1Position 
	local normalizedDirection = positionDifference.unit 
		
	local RUN_DISTANCE = 10 
	local targetAvoidanceLocation = character1Position + normalizedDirection * -1 * RUN_DISTANCE
end

function Check()
	local Players = game.Players:GetPlayers()
	local List = {}
	for _, player in pairs(Players) do
		if player.Character then
			local Char = player.Character
			if (Char.HumanoidRootPart.Position - RootPart.Position).Magnitude < ViewDistance then
				local raycastParams = RaycastParams.new()
				raycastParams.FilterDescendantsInstances = {player.Character,Character}
				raycastParams.FilterType = Enum.RaycastFilterType.Exclude
				for _, player in pairs(game.Players:GetPlayers()) do
					if player.Character then
						table.insert(raycastParams.FilterDescendantsInstances,player.Character)
					end
				end
				local raycastResult = workspace:Raycast(script.Parent.Head.Position, Char.HumanoidRootPart.Position - RootPart.Position, raycastParams)
				if raycastResult == nil or target == Char then
					table.insert(List,player.Character)
				end
			end
		end
	end
	return List
end

function GetTargetInList(List)
	local Closets = nil
	for _, TempCharacter in pairs(List) do
		if TempCharacter.Humanoid.Health > 0 then
			if Closets == nil then
				Closets = TempCharacter
			elseif (TempCharacter.HumanoidRootPart.Position - RootPart.Position).Magnitude < (Closets.HumanoidRootPart.Position - RootPart.Position).Magnitude then
				Closets = TempCharacter
			end
		end
	end
	return Closets
end

function Wander(Yieldable)
	local Position = RootPart.Position + Vector3.new(math.random(-100,100),0,math.random(-100,100))
	WalkTo(Position)
	local TimedOut = false
	moveto = Humanoid.MoveToFinished:Connect(function(reached)
		if reached == false then
			TimedOut = true
			moveto:Disconnect()
		end
	end)
	if Yieldable then
		local nearby
		repeat
			wait(.1)
			nearby = Check()
		until (Position - RootPart.Position).Magnitude < 5 or TimedOut == true or #nearby > 0
		if #nearby > 0 then
			return nearby
		else
			return false
		end
	end
end

function Raycast(Origin: Vector3, EndGoal: Vector3,Exclude)
	local TableParams = {Character}
	local raycastParams = RaycastParams.new()
	raycastParams.FilterDescendantsInstances = {Character}
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	for _, player in pairs(game.Players:GetPlayers()) do
		if player.Character then
			table.insert(TableParams,player.Character)
		end
	end
	for _, player in pairs(Exclude) do
		table.insert(TableParams,player)
	end
	raycastParams.FilterDescendantsInstances = TableParams
	local Cast = workspace:Raycast(Origin,EndGoal - Origin,raycastParams)
	return Cast
end

while true do
	wait()
	local nearby
	if target == nil and not lastseenpos then
		Humanoid.WalkSpeed = WalkSpeed
		nearby = Wander(true)
	end
	if nearby or target or lastseenpos then
		Humanoid.WalkSpeed = ChaseSpeed
		if target == nil and not lastseenpos then
			--RootPart.Notice:Play()
		end
		local NewNearby = Check()
		target = GetTargetInList(NewNearby)
		if target then
			local cast = Raycast(RootPart.Position,target.HumanoidRootPart.Position,{target})
			Stare(target.Head)
			if cast == nil then
				print("MOVE")
				Humanoid:MoveTo(target.HumanoidRootPart.Position)
				lastseenpos = target.HumanoidRootPart.Position
			else
				print("and we're shootin")
				WalkTo(target.HumanoidRootPart.Position,false)
			end
		else
			print("news eh?")
			if lastseenpos then
				WalkTo(lastseenpos)
				if (lastseenpos - RootPart.Position).Magnitude < 5 then
					lastseenpos = nil
				end
			end
		end
	end
end

1 Like

I figured out more of the problem. He thinks he can walk up the wall. the path action is set to walk, and the walk point is up on the wall.

im having this exact problem what have you done to fix it?

Take a look at this question: Pathfinding service is stupid You’re missing some settings that will help that.

local AGENT_PARAMS = {
	AgentRadius = 5,
	AgentHeight = 5,
	AgentCanJump = true,
	AgentJumpHeight = 10,
	AgentMaxSlope = 45,
	WaypointSpacing = 6,
	Costs = {
		[Enum.Material.Sand] = math.huge,
		[Enum.Material.Concrete] = math.huge
	}
}

Costs like this make them not walk on that material at all. You can get very creative with how you use this. That is getting a bit extreme when needed. Most of the time AgentRadius can cure this.

Sorry, this is old and I have already found a solution.

If anyone else is having issues, check these:

No gaps in walls
Wall is high enough (he was trying to go over the wall, or he thought he could walk over the wall)
Mess with agent params

I am pretty sure he was trying to jump, when he couldn’t.

1 Like