Quick answer: NavMeshObstacle carving is delayed because Carve Only Stationary is enabled by default, waiting 0.5 seconds after the obstacle stops moving before carving. Uncheck Carve Only Stationary for immediate carving, lower Time To Stationary for faster response, and reduce Move Threshold for more frequent updates during movement.

Here is how to fix delayed NavMeshObstacle carving in Unity. You place a barricade, agents should path around it, but they walk straight through it for half a second before the NavMesh updates. Or a door closes and agents still try to walk through it for a noticeable delay. The carving system is working correctly — it is just configured for a use case that does not match yours. Understanding the three carving parameters fixes this immediately.

The Symptom

A NavMeshObstacle with Carve enabled shows these behaviors:

The NavMesh debug visualization (Navigation window > Show NavMesh) confirms that the hole appears late or not at all during movement.

How Carving Works

Carve mode. When Carve is enabled on a NavMeshObstacle, Unity cuts a rectangular hole in the NavMesh matching the obstacle’s shape. Agents treat the hole as unwalkable and path around it. Without Carve, the obstacle only provides avoidance steering — agents steer away but can still be pushed through.

Carve Only Stationary. This is the key parameter. When enabled (default), the obstacle only carves the NavMesh after it has been stationary for Time To Stationary seconds. While moving, it acts as a non-carving avoidance obstacle. This is a performance optimization — carving is expensive and doing it every frame for moving objects would kill performance.

Time To Stationary. Default 0.5 seconds. After the obstacle stops moving (velocity drops below Move Threshold per frame), Unity waits this long before carving. Lower values make carving more responsive but can cause frequent NavMesh rebuilds if the obstacle vibrates or settles slowly.

Move Threshold. Default 0.1 units. The minimum distance the obstacle must move before Unity considers it “moving” and updates the carve position. Also controls how often a continuously moving obstacle (with Carve Only Stationary off) updates its hole.

The Fix

For stationary obstacles that are placed or spawned (barricades, walls, closed doors):

// Fast carving for placed obstacles
NavMeshObstacle obstacle = GetComponent<NavMeshObstacle>();
obstacle.carving = true;
obstacle.carveOnlyStationary = true;  // fine for stationary objects
obstacle.carvingTimeToStationary = 0.1f; // reduce from 0.5 to 0.1
obstacle.carvingMoveThreshold = 0.05f; // more sensitive movement detection

Reducing Time To Stationary from 0.5 to 0.1 makes carving feel nearly instant for objects that are placed once and stay put. The 0.1 second delay is imperceptible to players.

For moving obstacles that must carve while moving (sliding doors, moving platforms):

// Continuous carving for moving obstacles
NavMeshObstacle obstacle = GetComponent<NavMeshObstacle>();
obstacle.carving = true;
obstacle.carveOnlyStationary = false; // carve while moving
obstacle.carvingMoveThreshold = 0.2f; // update every 0.2 units of movement

Disabling Carve Only Stationary makes the obstacle carve continuously. This is more expensive — the NavMesh is rebuilt around this obstacle every time it moves beyond Move Threshold. Use sparingly. A scene with dozens of continuously carving obstacles will have performance problems.

For fast-moving obstacles (vehicles, projectiles): Do not use carving at all. Carving cannot keep up with fast movement and causes constant NavMesh rebuilds. Use the obstacle in non-carving mode (avoidance only) and let agent avoidance handle steering.

// Avoidance only, no carving — for fast-moving objects
NavMeshObstacle obstacle = GetComponent<NavMeshObstacle>();
obstacle.carving = false; // avoidance steering only

Door Pattern

Doors are the most common carving use case. A closed door should block the NavMesh. An open door should allow passage. Toggle carving when the door state changes:

public void SetDoorState(bool isClosed)
{
    NavMeshObstacle obstacle = GetComponent<NavMeshObstacle>();
    obstacle.carving = isClosed;
    obstacle.carveOnlyStationary = false; // immediate effect

    // Optionally disable the obstacle entirely when open
    obstacle.enabled = isClosed;
}

Disabling the obstacle component entirely when the door is open removes both the carve hole and the avoidance radius, giving agents full passage.

Performance Considerations

Each carving update rebuilds a local patch of the NavMesh. The cost scales with the number of simultaneously carving obstacles. Guidelines:

Profile with the Profiler window. Look for NavMesh.CarveUpdate in the CPU timeline. If it spikes, reduce the number of active carving obstacles or increase Move Threshold.

“Carve Only Stationary exists because carving every frame is expensive. When the delay matters more than the CPU cost, turn it off. When performance matters more, leave it on and reduce Time To Stationary.”

Related Issues

For agents walking through each other, adjust the NavMeshAgent avoidance priority and radius. For agents unable to find paths around obstacles, ensure the carved area does not completely block all routes — agents need an alternative path. For NavMesh not matching terrain after modification, use NavMeshSurface.UpdateNavMesh for runtime rebaking.

Carve Only Stationary off for doors. Time To Stationary 0.1 for placed objects. No carving for fast movers. Profile CarveUpdate.