Search Unity

[Script] Baking navmeshes for hidden objects.

Discussion in 'Assets and Asset Store' started by YorickVanVliet, Mar 19, 2012.

  1. YorickVanVliet

    YorickVanVliet

    Joined:
    Nov 14, 2009
    Posts:
    22
    While using the new NavMesh features that came with Unity 3.5 we found a rather intresting feature. It seems that GameObjects where the Renderer is disabled arent included in the NavMesh. They arent baked at all, and the NavAgents cant find the NavMesh. After filing a bug report our assumptions where confirmed, its supposed to be this way.

    The workaround for this feature is to enable all renderers, bake the NavMesh and then disable the renderers again. Luckily Unity is easily extended, which saves us a lot of work. The following script adds a menu item which does this automaticly.

    Code (csharp):
    1.  
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. /// <summary>
    7. /// Unity doesnt bake colliders without an active renderer in the navmesh. So enable the renderer, bake, then disable again.
    8. /// </summary>
    9. public class NavMeshFixer : ScriptableObject
    10. {
    11.     [MenuItem("Paladin/Fix Navigation Mesh")]
    12.     public static void FixNavMesh()
    13.     {        
    14.         Undo.RegisterSceneUndo("BakeNavMesh");
    15.  
    16.         List<Renderer> disabledObjects = new List<Renderer>(); //Keep a list of old objects
    17.  
    18.         foreach (Renderer item in Object.FindObjectsOfType(typeof(Renderer))) //Loop over all renderers
    19.         {
    20.             //Check if its marked as NavigationStatic, and it has a disabled renderer
    21.             if (GameObjectUtility.AreStaticEditorFlagsSet(item.gameObject, StaticEditorFlags.NavigationStatic)  
    22.                 !item.enabled)
    23.             {
    24.                 disabledObjects.Add(item);
    25.                 item.renderer.enabled = true; //Temporary enable it.
    26.             }            
    27.         }
    28.  
    29.         NavMeshBuilder.BuildNavMesh(); //Trigger the navmesh to build.
    30.  
    31.         disabledObjects.ForEach( obj => obj.enabled = false ); //Disable the objects again.
    32.  
    33.         Debug.Log(string.Format("Done building navmesh, {0} objects affected.", disabledObjects.Count));
    34.     }
    35. }
    36.  
    So the next time you want to build your mesh, and have invisible objects, use the button at Paladin/Fix Navigation Mesh :)
     
    Last edited: Mar 19, 2012
    AndreiKubyshkin and anisimovdev like this.
  2. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    This is incredibly useful. And to think no one has thanked you for it yet! You're the best.
     
  3. Evil-Dog

    Evil-Dog

    Joined:
    Oct 4, 2011
    Posts:
    134
    Yeah, thanks man! great job
     
  4. CWolfs

    CWolfs

    Joined:
    Dec 18, 2012
    Posts:
    1
    Just found this 'non-bug' myself. Thank you very much for a good script.
     
  5. mrgarcialuigi

    mrgarcialuigi

    Joined:
    Feb 11, 2015
    Posts:
    12
  6. Rokie14

    Rokie14

    Joined:
    Jul 30, 2015
    Posts:
    4
    Hi Garcialuigi!
    Im a rookie and i reading your project. This is my project:
    I have two map and one character moving on it (two independent map). The maps selected by click Menu. I want to make character moving on two maps at two different times (click menu>selected map). But I can not because I only bake navigation by hand. Can you help me, please!

    Besides, NavMesh was created while characters move?? Can you tell me your method? Thanks you!