Skip to main content

Navigator

Owns a Types.Pathfinder and a Types.Mover. MoveTo is safe to call every tick with a moving target: the navigator re-plans on a cadence, re-plans when the target moves, retries when the mover gets stuck, and reports through GetStatus and Arrived. Every Agent built with both a pathfinder and a mover has one at agent.Navigator.

A path to a target that stays put is followed to its end by default. Two options change that for a level that moves under the agent (doors, moving platforms, other NPCs): a pathfinder with a Blocked signal (Navmesh has one) makes the navigator re-plan on the next cadence tick, and MaxPathAge plans again once the current path is that many seconds old, whether or not anything is known to have changed. Both cost one plan each time; neither plans more often than RepathInterval.

Arrival is judged by horizontal distance within ArriveDistance, with the height difference allowed up to ArriveHeight: a humanoid's root and a floor waypoint sit at different heights, but a target on the floor above is not reached.

A step whose Label has a handler (see Builder:OnStep) is where the navigator does the one thing a mover cannot: it stops at the step, reports Interacting, runs the handler, and then walks the rest of the path. MoveTo with the same target keeps waiting; a new target or Stop abandons the path and the handler's return is ignored.

With a direct pathfinder (Builder:UseDirect) the navigator walks straight at a target it can reach in a line and only plans when it cannot, or when walking straight stopped making progress. IsDirect says which it is doing.

Functions​

new​

Navigator.new(
pathfinder: Pathfinder,
mover: Mover,
agent: Agent,--

Handed to FindPath so a pathfinder can read the blackboard.

steps: {[string]: StepHandler | StepRegistration}?,--

Handlers by step label.

direct: Pathfinder?--

Asked first whether the agent can walk straight at the target; must not yield. See Builder:UseDirect.

) → Navigator

MoveTo​

Navigator.MoveTo(
self: Navigator,
target: Vector3
) → ()

Heads to target. Call it every tick with a moving target; a plan only happens when the target is new, has moved more than RepathDistance since the last plan, the last plan failed or ran out, the pathfinder reported the path blocked, or the path is older than MaxPathAge, and never more often than RepathInterval. A new target after arriving is treated as new: the status leaves Arrived at once.

Stop​

Navigator.Stop(self: Navigator) → ()

Forgets the target and halts the mover. Fires Arrived(false) if a target was in progress.

GetStatus​

Navigator.GetStatus(self: Navigator) → PathStatus

GetTarget​

Navigator.GetTarget(self: Navigator) → Vector3?

GetPath​

Navigator.GetPath(self: Navigator) → Path?--

The last path planned, kept until the next plan or Stop.

GetRemainingDistance​

Navigator.GetRemainingDistance(self: Navigator) → number--

Studs left along the current path from where the agent is, math.huge when there is no path.

The distance still to walk, around corners rather than through walls: from the agent to the next step of the path, then along the rest of it. What the original VluxyAI pathfinding called GoalDistance; a brain can use it to give up on a target that is too far to walk to.

Step​

Navigator.Step(
self: Navigator,
deltaTime: number
) → ()

One tick. Retries a plan that is due even when nobody called MoveTo this tick, so a state that called MoveTo once with a fixed position still gets there after a stuck mover, a blocked path or a path past MaxPathAge.

IsDirect​

Navigator.IsDirect(self: Navigator) → boolean

Whether the agent is walking straight at its target (see Builder:UseDirect) rather than following a planned path.

Destroy​

Navigator.Destroy(self: Navigator) → ()

Stops and disconnects from the mover. The mover and pathfinder are not destroyed; the agent owns those.

Show raw api
{
    "functions": [
        {
            "name": "new",
            "desc": "",
            "params": [
                {
                    "name": "pathfinder",
                    "desc": "",
                    "lua_type": "Pathfinder"
                },
                {
                    "name": "mover",
                    "desc": "",
                    "lua_type": "Mover"
                },
                {
                    "name": "agent",
                    "desc": "Handed to `FindPath` so a pathfinder can read the blackboard.",
                    "lua_type": "Agent"
                },
                {
                    "name": "options",
                    "desc": "",
                    "lua_type": "NavigationOptions?"
                },
                {
                    "name": "steps",
                    "desc": "Handlers by step label.",
                    "lua_type": "{ [string]: StepHandler | StepRegistration }?"
                },
                {
                    "name": "direct",
                    "desc": "Asked first whether the agent can walk straight at the target; must not yield. See [Builder:UseDirect].",
                    "lua_type": "Pathfinder?"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Navigator"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 176,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "MoveTo",
            "desc": "Heads to `target`. Call it every tick with a moving target; a plan only happens when the\ntarget is new, has moved more than `RepathDistance` since the last plan, the last plan failed\nor ran out, the pathfinder reported the path blocked, or the path is older than `MaxPathAge`,\nand never more often than `RepathInterval`. A new target after arriving is treated as new: the\nstatus leaves `Arrived` at once.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                },
                {
                    "name": "target",
                    "desc": "",
                    "lua_type": "Vector3"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 803,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "Stop",
            "desc": "Forgets the target and halts the mover. Fires `Arrived(false)` if a target was in progress.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 841,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "GetStatus",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "PathStatus"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 881,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "GetTarget",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "Vector3?"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 889,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "GetPath",
            "desc": "",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                }
            ],
            "returns": [
                {
                    "desc": "The last path planned, kept until the next plan or `Stop`.",
                    "lua_type": "Path?"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 897,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "GetRemainingDistance",
            "desc": "The distance still to walk, around corners rather than through walls: from the agent to the\nnext step of the path, then along the rest of it. What the original VluxyAI pathfinding called\n`GoalDistance`; a brain can use it to give up on a target that is too far to walk to.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                }
            ],
            "returns": [
                {
                    "desc": "Studs left along the current path from where the agent is, `math.huge` when there is no path.",
                    "lua_type": "number"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 909,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "Step",
            "desc": "One tick. Retries a plan that is due even when nobody called `MoveTo` this tick, so a state\nthat called `MoveTo` once with a fixed position still gets there after a stuck mover, a blocked\npath or a path past `MaxPathAge`.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                },
                {
                    "name": "deltaTime",
                    "desc": "",
                    "lua_type": "number"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 990,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "IsDirect",
            "desc": "Whether the agent is walking straight at its target (see [Builder:UseDirect]) rather than\nfollowing a planned path.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                }
            ],
            "returns": [
                {
                    "desc": "",
                    "lua_type": "boolean"
                }
            ],
            "function_type": "static",
            "source": {
                "line": 1022,
                "path": "lib/Navigator.luau"
            }
        },
        {
            "name": "Destroy",
            "desc": "Stops and disconnects from the mover. The mover and pathfinder are not destroyed; the agent\nowns those.",
            "params": [
                {
                    "name": "self",
                    "desc": "",
                    "lua_type": "Navigator"
                }
            ],
            "returns": [],
            "function_type": "static",
            "source": {
                "line": 1032,
                "path": "lib/Navigator.luau"
            }
        }
    ],
    "properties": [],
    "types": [],
    "name": "Navigator",
    "desc": "Owns a [Types.Pathfinder] and a [Types.Mover]. `MoveTo` is safe to call every tick with a\nmoving target: the navigator re-plans on a cadence, re-plans when the target moves, retries when\nthe mover gets stuck, and reports through `GetStatus` and `Arrived`. Every [Agent] built with\nboth a pathfinder and a mover has one at `agent.Navigator`.\n\nA path to a target that stays put is followed to its end by default. Two options change that\nfor a level that moves under the agent (doors, moving platforms, other NPCs): a pathfinder\nwith a `Blocked` signal ([Navmesh] has one) makes the navigator re-plan on the next cadence\ntick, and `MaxPathAge` plans again once the current path is that many seconds old, whether or\nnot anything is known to have changed. Both cost one plan each time; neither plans more often\nthan `RepathInterval`.\n\nArrival is judged by horizontal distance within `ArriveDistance`, with the height difference\nallowed up to `ArriveHeight`: a humanoid's root and a floor waypoint sit at different heights,\nbut a target on the floor above is not reached.\n\nA step whose `Label` has a handler (see [Builder:OnStep]) is where the navigator does the one\nthing a mover cannot: it stops at the step, reports `Interacting`, runs the handler, and then\nwalks the rest of the path. `MoveTo` with the same target keeps waiting; a new target or `Stop`\nabandons the path and the handler's return is ignored.\n\nWith a direct pathfinder ([Builder:UseDirect]) the navigator walks straight at a target it can\nreach in a line and only plans when it cannot, or when walking straight stopped making\nprogress. `IsDirect` says which it is doing.",
    "source": {
        "line": 165,
        "path": "lib/Navigator.luau"
    }
}