Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Navmesh Surface bakes slightly above the surface

Discussion in 'AI & Navigation Previews' started by Drowning-Monkeys, Dec 12, 2017.

  1. Drowning-Monkeys

    Drowning-Monkeys

    Joined:
    Mar 6, 2013
    Posts:
    328
    Hi there,

    so every navmesh surface i bake is approximately 0.1 units above the actual surface it's representing. The result is that all of my character's are 'floating in air'. I noticed that there's a "Base Offset" variable to help alleviate this problem but before i use it i wanted to know if this was expected behavior and if i should be approaching having navmesh agent's in some other way.

    Also, I know that in the original NavMesh you could bake a HeightMesh to solve this problem but that doesn't seem to be an option anymore

    Thanks!
     
    Last edited: Dec 12, 2017
  2. Claytonious

    Claytonious

    Joined:
    Feb 16, 2009
    Posts:
    904
    This lack of the bake height mesh option is the sole reason we are still using the legacy NavMesh workflows instead of the new components. We also have the problem of our characters floating in the air above our terrains without that option.

    Note that we don't care about the height mesh itself - we are only using it because it seems to solve the problem of the nav mesh incorrectly reporting positions ABOVE the terrain from which it was built.
     
  3. Multithreaded_Games

    Multithreaded_Games

    Joined:
    Jul 6, 2015
    Posts:
    122
    Yeah, it's dumb. Setting the voxel size higher (or lower, I can't remember) should fix this problem at the expense of taking longer to bake.
     
    pdinklag likes this.
  4. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    725
    What I'm doing for baking navmeshes is instead of using default terrain or objects, creating a multitude of planes and setting them to the only game objects in the scene as static.

    I then bake the navmesh and can position the planes beneath the surface of my terrain or floor. After the mesh is baked, just disable the planes so that they're invisible and then you have just your navmesh. Perhaps throw them in a parent object named "Invisible Obstacle Course" or something for organizations sake.

    This will also keep your nav meshes very small, they bake in about a second for me.

    Of course if you're creating a free roaming or large scale game this wouldn't work, but if you're creating a large free roaming game you really shouldn't be using Unity's native navmesh system in the first place I feel.
     
  5. rcabot

    rcabot

    Joined:
    Oct 24, 2014
    Posts:
    6
    Put this in another thread, but if you're not too concerned about performance in the short term, you can try a solution which corrects for incorrect height positioning at runtime:
    Code (CSharp):
    1. private void CorrectBaseHeight()
    2.     {
    3.         NavMeshHit navhit;
    4.         if (NavMesh.SamplePosition(GameObject.transform.position, out navhit, 10f, NavMesh.AllAreas))
    5.         {
    6.             Ray r = new Ray(navhit.position, Vector3.down);
    7.             RaycastHit hit;
    8.             if (Physics.Raycast(r, out hit, 10f, LayerMask.GetMask("Level")))
    9.             {
    10.                 _nav.baseOffset = -hit.distance;
    11.             }
    12.         }
    13.     }
     
    LaneFox and astracat111 like this.
  6. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,364
    Yes there should be offset control somewhere but agents commonly have a root with all control components including the navmesh agent, anyway, so that root is easy to offset.
     
  7. tawdry

    tawdry

    Joined:
    Sep 3, 2014
    Posts:
    1,357
    Hi astra I'm someone trying to create a free large roaming world why would you recommend not using unity's native navmesh?What other solution is there instead?
     
    astracat111 and entropicjoey1 like this.
  8. craig4android

    craig4android

    Joined:
    May 8, 2019
    Posts:
    124
    someone found a solution for this? I hate this offset
     
  9. astracat111

    astracat111

    Joined:
    Sep 21, 2016
    Posts:
    725
    I actually just use Unity's native navmesh. I'm sure there are better ways of doing it, but this works for what I need.

    I just use an offset variable for my npc class.

    Code (CSharp):
    1. class NPC {
    2.     NavMeshAgent navMeshAgent;
    3.     float navMeshOffset;
    4.  
    5.     void Awake() {
    6.         navMeshAgent = this.gameObject.GetComponent<NavMeshAgent>();
    7.     }
    8.  
    9.     void Update() {
    10.         navMeshAgent.offset = navMeshOffset; //Not sure if this is correct off the top of my head
    11.     }
    12. }
     
  10. craig4android

    craig4android

    Joined:
    May 8, 2019
    Posts:
    124
    it's called NavMeshAgent.baseOffset
    and you definitely shouldn't use it on all update calls, but in start or awake.
     
  11. pdinklag

    pdinklag

    Joined:
    Jan 24, 2017
    Posts:
    154
    You're right about not doing it every frame, but the problem is that when changing between slopes and planes, the situation may actually change every frame.

    For me, decreasing the voxel size (= increasing accuracy) solved the issue. The bake time didn't change notably, but my scenes are also not too complex. I would definitely recommend trying this over changing the offset in every frame.