Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

PathfindingService Navmesh Not Updating On Runtime?

Asked by 6 years ago
Edited 6 years ago

On the wiki reference for PathfindingService (API:Class/PathfindingService), it states that "PathfindingService generates a navigation mesh over all of the parts in the place while a game is running" and "If the geometry of the place changes, for example if a part moves or is created, then the navigation mesh will be recalculated." It also states this on the DevForum post regarding the release of the new pathfinding system: "Dynamic Navigation Mesh generation: The navmesh will automatically regenerate when obstacles move around the world." (Introducing: Roblox Pathfinding)

However, my navmesh is not updating while running the game with the studio "run" button, nor does it seem to update while playing through the normal client.

I have a script that spawns a new brick a second after the game starts running and resizes a premade brick in the Y axis, to make what was previously a jumpable surface too high to be jumped upon. The navmesh does not take these changes into account. (Screenshot)

Why isn't the navmesh updating in real time, even though it is supposed to? Thanks.

Edit: After some more playing around, I found out that the navmesh only updates with a new call of FindPathAsync of PathfindingService. CheckOcclusionAsync is supposed to check if a path is made invalid, but my implementation doesn't seem to work. Here is my script for my pathfinding:

local pathfinding = game:GetService("PathfindingService")

local startBrick = workspace.NPC.Torso
local endBrick = workspace.GoBrick
local reachedEnd = false

function getPath()
    path = pathfinding:FindPathAsync(startBrick.Position, endBrick.Position)
    waypoints = path:GetWaypoints()
end


--Works fine, not related to this problem
function drawWaypoints()
    --Shows path visually
    for i = 1, #waypoints, 1 do
        local marker = game.ReplicatedStorage.WP:Clone()
        marker.Name = "WP" .. i
        marker.Parent = workspace.PathPoints
        marker.Position = waypoints[i].Position
        if waypoints[i].Action == Enum.PathWaypointAction.Jump then
            marker.BrickColor = BrickColor.new(255, 0, 0)
        end
    end
end

function move()
    local chara = workspace.NPC.Humanoid
    local blocked = -1

    for i = 1, #waypoints, 1 do
        local blocked = path:CheckOcclusionAsync(i)
        if blocked ~= -1 then -- -1 means not blocked
            return
        end

        chara:MoveTo(waypoints[i].Position)

        local lastWPs = false
        if waypoints[i-1] ~= nil then
            if waypoints[i].Position.Y > waypoints[i-1].Position.Y then
                lastWPs = true
            end
        end

        if (waypoints[i].Action == Enum.PathWaypointAction.Jump) and (lastWPs) then --Only jump if the next waypoint is higher in Y than current
            chara.Jump = true
        end

        chara.MoveToFinished:Wait()
    end
    reachedEnd = true
end
local t = 1
while not reachedEnd do
    getPath()
    drawWaypoints()
    move()
    t = t + 1
end

So it seems that CheckOcclusionAsync is never making blocked ~= -1. The wiki page isn't very helpful for the function. It wants an int start as the parameter, but what exactly is that int? I've been passing it the index of my current waypoint, but that seems to be the wrong assumption.

Answer this question