NavMesh and Pathfinding for Mobile Games: Expert Development
Imagine a mobile RTS with a hundred units. Each uses A*—FPS drops to 10. Our navigation systems solve this. We have been developing navigation systems for mobile games for 5+ years, with over 20 projects using NavMesh and pathfinding. Quality navigation is the difference between a playable project and an abandoned prototype. Here we explain how we tackle challenges: from static NavMesh to Flow Field for swarms.
An enemy walking through walls or an NPC stuck in a corner—that's not a bug, it's the absence of a proper navigation system. On mobile devices, adding a hundred agents with full pathfinding can drop FPS to 15. We combine NavMesh, A*, and Flow Field to ensure smooth movement with minimal CPU consumption. Our experience shows that correct NavMesh baking eliminates 80% of navigation problems. We guarantee that every agent reaches its goal without getting stuck.
How NavMesh Works on Mobile Devices
NavMesh is a simplified representation of the level that an agent can traverse. It is built once when the level loads (or baked in the editor beforehand). In Unity, it is the built-in NavMeshAgent; in Godot, NavigationServer3D.
Key NavMesh baking parameters that affect quality:
Agent Radius: 0.4 // capsule radius — NavMesh is built with an offset
Agent Height: 1.8 // height — for detecting low passages
Max Slope: 45° // maximum climbable slope
Step Height: 0.4 // step height the agent can overcome
On mobile devices, it's critical: bake NavMesh in the Editor beforehand, not at runtime. Runtime baking (via NavMeshBuilder.BuildNavMeshAsync) takes 100–500ms and creates GC pressure. For dynamic obstacles, use NavMeshObstacle with Carve = true—it carves itself out of the NavMesh in 10–30ms.
Why A* Is Not Always Suitable for Mass Agents
For pathfinding, Unity uses the built-in A* algorithm with Euclidean distance heuristic. For most mobile games, this is optimal. But there are scenarios where standard A* fails:
- Dynamic obstacles—player places barricades, door closes. Solution is
NavMeshObstaclewithCarve = true, but recalculation is expensive. An alternative for frequent changes is Flow Field pathfinding: precompute a vector field for the target, agents follow the field without individual path searching. - Many agents targeting one point—zombie games, tower defense. A* for each agent individually with 100+ agents kills performance. Flow Field is computed once for the entire field—agents read the value of their cell. O(1) per agent vs O(n log n) for A*.
| Characteristic | A* | Flow Field |
|---|---|---|
| Computation per agent | O(n log n) | O(1) |
| Dynamic obstacle support | Requires path recalculation for each agent | Requires field recalculation (once for all) |
| Memory | Low (agent path) | Medium (vector field of map size) |
| Recommended agent count | Up to 50 | 50–500 |
| Best scenario | Sparse agents, rare changes | Swarm behavior, stable map |
Flow Field is 5–10x faster than A* with 100+ agents—proven on real projects. In one case, we reduced development costs by $2000 by replacing A* with Flow Field.
// Unity: basic Flow Field query for a tile map
public class FlowField {
private Vector2[,] directions;
private int width, height;
public void Calculate(Vector2Int target, bool[,] obstacles) {
var costField = new int[width, height];
var queue = new Queue<Vector2Int>();
queue.Enqueue(target);
costField[target.x, target.y] = 0;
while (queue.Count > 0) {
var current = queue.Dequeue();
foreach (var neighbor in GetNeighbors(current)) {
if (!obstacles[neighbor.x, neighbor.y] &&
costField[neighbor.x, neighbor.y] == int.MaxValue) {
costField[neighbor.x, neighbor.y] = costField[current.x, current.y] + 1;
queue.Enqueue(neighbor);
}
}
}
}
public Vector2 GetDirection(Vector2Int position) => directions[position.x, position.y];
}
How to Implement Smooth NPC Movement?
Pathfinding gives a route—a list of waypoints. Steering behaviours turn this into smooth movement:
- Seek / Arrive: move towards the target with deceleration when approaching
- Obstacle Avoidance: evade dynamic obstacles via Raycast (distance 2–3 units)
- Separation: agents avoid clustering (radius 1.5 units)
- Cohesion: group stays together (for flocking behavior)
NavMeshAgent includes basic steering behaviours. For fine-tuning, use RVOSimulator from the com.unity.ai.navigation package (ORCA algorithm). This gives realistic collision avoidance without mutual deadlocks.
How to Ensure Performance on Mobile?
Do not recalculate the path every frame. Each NavMeshAgent.SetDestination() triggers a new pathfinding request. For chasing a player, recalculating every 0.3–0.5 seconds is sufficient:
private float pathUpdateTimer = 0f;
private const float PATH_UPDATE_INTERVAL = 0.3f;
void Update() {
pathUpdateTimer += Time.deltaTime;
if (pathUpdateTimer >= PATH_UPDATE_INTERVAL) {
agent.SetDestination(player.position);
pathUpdateTimer = 0f;
}
}
LOD for navigation. Off-screen agents disable NavMeshAgent and use waypoint teleportation. Full pathfinding is enabled only when in frustum. This saves 30% CPU.
Unity Job System for A*. If custom pathfinding on a large map is needed, IJob + NativeArray<> moves computation off the main thread. Burst Compiler gives ~10x speedup. In one project, we reduced path calculation time from 5ms to 0.4ms.
Debugging and Visualization
Pathfinding is hard to debug without visualization. In the Editor, we draw the NavMesh path:
void OnDrawGizmos() {
if (agent != null && agent.hasPath) {
Gizmos.color = Color.yellow;
var corners = agent.path.corners;
for (int i = 0; i < corners.Length - 1; i++) {
Gizmos.DrawLine(corners[i], corners[i + 1]);
}
}
}
We also refer to the Unity NavMesh documentation to verify baking parameters.
Code optimization details
For Flow Field, we use NativeArray<Vector2> with the Job System—giving 10x speedup on mobile devices.
Process
- Level analysis—static geometry, dynamic obstacles, agent count (no more than 500 on an average device).
- Algorithm selection—NavMesh + A* for typical scenarios, Flow Field for mass agents.
- NavMesh configuration—baking parameters, integration with geometry.
- Steering implementation—tuning smoothness, obstacle avoidance.
- Optimization—LOD, update intervals, Job System.
- Testing—on target devices with Unity Profiler (FPS, memory).
| Stage | Duration | What's included |
|---|---|---|
| Analysis | 1 day | Geometry assessment, NPC count, performance evaluation |
| Design | 1–2 days | Algorithm selection, AI specification |
| Implementation | 3–10 days | Coding, integration with game logic |
| Optimization | 2–3 days | LOD, Job System, profiling |
| Testing | 1–2 days | Verification on 3–5 devices |
What's Included
- Ready navigation system with source code
- Documentation for NavMesh parameter setup
- Team training (2 hours online)
- 2 weeks of technical support after delivery
- Adaptation for target devices (iOS/Android)
Order navigation system development—get a consultation and estimate within 24 hours.
Estimated Timelines
- Basic navigation via NavMeshAgent for 5–10 agent types—3–5 days.
- Custom system with Flow Field, dynamic obstacles, and LOD optimization—2–4 weeks.
Contact us to discuss your project. We will analyze your scenario for free and propose the optimal solution.







