Skip to content

Instantly share code, notes, and snippets.

@bsimser
Last active February 20, 2026 14:18
Show Gist options
  • Select an option

  • Save bsimser/1e5d1fe2913cd7dca4fafa0e4f18d02b to your computer and use it in GitHub Desktop.

Select an option

Save bsimser/1e5d1fe2913cd7dca4fafa0e4f18d02b to your computer and use it in GitHub Desktop.
A way to bake your unity terrain trees into the nav mesh
///////////////////////////////////////////////////////////////////////////////
//
// This code is licensed under MIT license.
//
// Copyright © 2026 Bil Simser, https://www.simstools.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
///////////////////////////////////////////////////////////////////////////////
using UnityEditor;
using UnityEngine;
using UnityEngine.AI;
///////////////////////////////////////////////////////////////////////////////
///
/// 1. Make sure your tree prefab has a collider
/// 2. Go to your tool bar and click the obstacle baker. This will spawn a
/// capsule game object at every tree under a parent game object.
/// 3. Bake your nav mesh surface
/// 4. Delete the Obstacle object
///
///////////////////////////////////////////////////////////////////////////////
public class TreeObstacleBaker : EditorWindow
{
[MenuItem("Tools/Bake Trees With Temporary Capsules")]
public static void ShowWindow()
{
GetWindow<TreeObstacleBaker>("Tree Obstacle Baker");
}
private void OnGUI()
{
GUILayout.Label("Bake Terrain Trees into NavMesh (temporary capsules)", EditorStyles.boldLabel);
EditorGUILayout.Space(10);
if (GUILayout.Button("Generate Capsules for Trees"))
{
GenerateTreeCapsules();
}
}
private void GenerateTreeCapsules()
{
Terrain terrain = Terrain.activeTerrain;
if (terrain == null)
{
Debug.LogError("No active terrain found.");
return;
}
TreeInstance[] trees = terrain.terrainData.treeInstances;
if (trees.Length == 0)
{
Debug.LogWarning("No trees found on the terrain.");
return;
}
// Remove previous obstacles
GameObject oldParent = GameObject.Find("Tree_Obstacles");
if (oldParent != null) DestroyImmediate(oldParent);
GameObject parent = new GameObject("Tree_Obstacles");
Undo.RegisterCreatedObjectUndo(parent, "Create Tree Obstacles");
int createdCount = 0;
foreach (TreeInstance tree in trees)
{
// Convert tree local position to world
Vector3 worldPos = Vector3.Scale(tree.position, terrain.terrainData.size) + terrain.transform.position;
GameObject capsule = GameObject.CreatePrimitive(PrimitiveType.Capsule);
capsule.name = "TreeCapsule_" + createdCount;
capsule.transform.position = worldPos;
capsule.transform.SetParent(parent.transform);
// Adjust scale (example: 1 unit radius, height = terrain tree height)
float treeHeight = terrain.terrainData.size.y * 0.5f; // adjust as needed
capsule.transform.localScale = new Vector3(1f, treeHeight / 2f, 1f); // height in Unity capsule = scale.y * 2
capsule.isStatic = true; // mark as static for NavMesh baking
// Remove collider if desired after bake
// Or leave it for baking
// Collider col = capsule.GetComponent<Collider>();
createdCount++;
}
Debug.Log($"Created {createdCount} tree capsules. Bake NavMesh now and then you can delete the parent object.");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment