Rooms, Portals, and Navigation
Polygon Engine provides two independent, fixed-capacity world systems:
- Rooms and Portals conservatively reject renderers outside the camera's potentially visible portal chain.
- Navigation bakes height-aware grid samples and moves NavMesh Agent GameObjects along three-dimensional runtime paths.
Author both from View > Advanced Scene Authoring > Rooms & Navigation.
Rooms
A Room is an axis-aligned volume centered on the GameObject Transform plus its authored offset.
| Property | Meaning |
|---|---|
| Enabled | Include the room in runtime queries |
| Name | Unique scene-local label |
| Size | Width, height, and depth of the volume |
| Offset | Local offset from the room GameObject position |
| Priority | Tie-breaker when volumes overlap; highest wins |
Assign environment Mesh Renderers with Renderer Room. An unassigned renderer remains globally eligible for the normal visibility path.
At runtime, the camera room is the highest-priority enabled Room whose AABB contains the camera. The renderer remains eligible when it is global or its assigned room is retained by the runtime portal traversal.
Portals and Recursive Connectivity
A Portal references Room A and Room B and stores an enabled/open state, opening width and height, and Two Sided flag. The PS1 runtime traverses the graph recursively:
- A can reach B through every enabled open Portal;
- B can reach A only when that Portal is Two Sided;
- every valid opening directly adjacent to the camera room is retained;
- later rooms are retained only when the incoming and outgoing conservative aperture cones overlap.
Each cone contains the complete authored rectangular opening. The test is deliberately broader than exact portal-plane clipping, so it can retain rooms that are not ultimately visible. Invalid graph references, missing or malformed portal transforms, an unknown camera room, a camera inside an opening, queue pressure, or other ambiguous data fail open instead of risking a missing room. Global and unknown room assignments also remain visible.
Editor Play Mode and the PS1 runtime share the same conservative aperture math, recursion limits and fail-open policy, so room eligibility matches for the same camera and scene state. Validate performance and final presentation in the packaged build. This system does not provide hardware occlusion queries, automatic room splitting, or automatic per-triangle room assignment.
Lua can change a Portal at runtime:
local doorPortal = -1
function Start(gameObjectId)
doorPortal = GameObject.Find("Door Portal")
end
function openDoor(gameObjectId)
Portal.SetOpen(doorPortal, true)
end
See the Portal Lua API.
Height-Aware Navigation Bake
Add NavMesh Surface to a root GameObject. Its volume establishes an X/Z grid and a vertical sampling range. The surface may rotate around Y. The surface center Y remains a backward-compatible base floor, while explicit traversable box faces add or replace quantized layers. The bake creates deterministic four-neighbour links between compatible samples.
| Surface property | Default | Bake effect |
|---|---|---|
| Size / Offset | 8,4,8 / 0,0,0 | Bounds the sampled volume |
| Cell Size | 0.50 | X/Z grid resolution |
| Cell Height | 0.25 | Quantizes sampled heights |
| Agent Radius | 0.30 | Expands obstacle clearance |
| Agent Height | 1.80 | Rejects nodes without enough headroom |
| Max Step | 0.35 | Maximum normal neighbour height difference |
| Max Slope | 45 degrees | Rejects steeper walkable faces |
| Max Drop | 1.50 | Maximum authored one-way WalkOff descent |
The bake can retain multiple Y samples at the same X/Z cell, allowing overlapping floors inside one surface volume. Increase the volume height and place explicit walkable geometry at each level.
Navigation Modifier Areas
Navigation Modifier classifies a Collider for the bake. Modifier geometry must be on a root GameObject.
| Area | Collider rule | Result |
|---|---|---|
| Obstacle | Non-trigger box or sphere | Blocks covered navigation cells |
| Walkable | Solid box | Samples the box's upper face as traversable geometry |
| Platform | Solid box | Same static bake behavior as Walkable; useful authoring label for platforms |
| WalkOff | Trigger volume | Allows downward-only links from covered source cells |
Walkable and Platform boxes may be rotated or sloped. The baker evaluates the
actual transformed upper plane, its height, and its slope. Platform is a
static bake classification; it does not add moving-platform velocity, rider
parenting, or dynamic rebaking.
A WalkOff link is created only when the destination is lower by more than Max Step and no more than Max Drop. It has no reverse upward link. The trigger marks permission to drop; it does not simulate falling or replace gameplay collision.
Ordinary enabled non-trigger Colliders are obstacles unless an enabled Walkable/Platform modifier classifies them otherwise. Ordinary obstacle boxes support Y rotation for the navigation bake. The NavMesh Surface and ordinary obstacles remain root, yaw-only authoring paths; explicit Walkable/Platform box sampling is the supported rotated-slope path.
Use Preview Navigation Bake to inspect node and directed-link counts, warnings, and errors before building. Its top-down graph uses node color to represent height. The preset menu offers:
| Preset | Cell Size / Height | Agent Radius / Height | Max Step / Slope / Drop |
|---|---|---|---|
| Balanced | 0.50 / 0.25 | 0.30 / 1.80 | 0.35 / 45 / 1.50 |
| Tight Indoor | 0.25 / 0.125 | 0.30 / 1.80 | 0.30 / 45 / 1.00 |
| Large Outdoor | 1.00 / 0.50 | 0.45 / 2.00 | 0.50 / 42 / 2.00 |
| Precision Platforming | 0.25 / 0.125 | 0.25 / 1.60 | 0.20 / 40 / 4.00 |
Apply Preset changes the bake parameters but not the surface Size or Offset. Preview the result again after any geometry or parameter change, then validate the packaged runtime path on its intended scene.
Navigation Agents
A NavMesh Agent must be on a root GameObject and reference one surface.
| Property | Meaning |
|---|---|
| Speed | Maximum movement speed |
| Acceleration | Rate used to approach maximum speed |
| Stopping Distance | Final waypoint tolerance |
| Rotate to Velocity | Turn Y rotation toward X/Z movement |
NavMeshAgent.SetDestination() finds a complete lowest-cost path with deterministic
Dijkstra search. It can follow authored links to connected surfaces and advances
the GameObject through three-dimensional baked waypoints. Requests above 32 path
points fail rather than returning a misleading partial route. Acceleration zero
applies full speed immediately. Check the boolean result of every request.
Navigation writes the root Transform. If another script moves an active agent, it recalculates the route from the new position against the existing bake, or stops if no complete route exists. It does not add Character Controller collision response, dynamic obstacle avoidance, or runtime geometry rebaking.
The bake is not an arbitrary triangle navmesh or Recast-style runtime system. See the NavMesh and NavMeshAgent Lua API.
First Navigable Scene
- Create a root GameObject named Navigation Surface. In View > Advanced Scene Authoring > Rooms & Navigation, add NavMeshSurface and keep it enabled. Place its center Y at floor height.
- The initial Size is 8 by 4 by 8 units and Cell Size is 0.5. A single unobstructed layer uses 256 nodes, the scene limit. For additional surfaces or stacked floors, reduce Size or increase Cell Size before adding more nodes. Presets change cell settings, not volume size.
- Mark solid floor boxes with Navigation Modifier > Walkable. Ordinary solid wall boxes block navigation. Keep this authoring geometry at the scene root. The navigation graph comes from the volume and colliders, not from visual mesh triangles.
- Create a root GameObject for the agent. Put its origin at foot height near a sampled point, add NavMeshAgent, and assign the enabled surface. Put the visible model on a child if its origin is at its center. An enabled agent's own Collider is excluded from static obstacle baking.
- Click Preview Navigation Bake. Check that both the starting area and destination have nodes connected by links. Thin walls must separate routes; adjust Cell Size and Agent Radius to keep corridors usable.
- Attach a Lua Behaviour and use the movement example. Restart Play Mode after editing navigation geometry. Export again to update the graph used on PS1.
Explicit Navigation Links
Add Navigation Link to a root GameObject to bridge a gap between samples or surfaces. Set Start Surface and End Surface when you need precise surface selection. The endpoint offsets use the link GameObject's local transform. Snap Distance limits how far each endpoint may project onto a node.
Enable Bidirectional for travel in both directions; otherwise only start to end is allowed. Cost Multiplier controls route preference. When several links connect the same nodes, the lowest cost is used. Preview reports endpoints that cannot snap or both snap to the same node.
The agent's assigned surface anchors the reachable network. Unconnected surfaces are not automatically merged. Traversal is straight movement along the authored segment: the link grants permission to cross it, so verify the clearance yourself. It does not automatically jump, animate a ladder, open a door, or wait for a lift.
Navigation Troubleshooting
| Symptom | Check |
|---|---|
| An enabled agent references a disabled surface | Enable both the surface GameObject and its component, or disable the agent |
| No walkable cells | Mark a solid floor as Walkable; check floor height, blocking colliders, volume bounds, and agent clearance |
| Destination rejected | Check endpoint height and distance from nodes, directed connectivity, and the 32-point path limit; use a small SamplePosition radius and check SetDestination |
| Route stops after a teleport | The new position cannot reach the existing goal; move onto a valid sample and request a new destination |
| Agent repeatedly restarts or barely accelerates | Do not request the same destination every frame or combine navigation with another movement controller |
| Scene changes are ignored during play | The graph is static; stop and restart Play Mode or export again after editing geometry |
Limits
| Resource | Limit |
|---|---|
| Rooms | 24 |
| Portals | 48 |
| NavMesh Surfaces | 4 |
| NavMesh Agents | 16 |
| Baked nodes | 256 |
| Baked directed links | 1,024 |
| Path points per request | 32 |
Increase cell size, reduce sampled floors, or split the scene when the graph approaches node or link capacity.