navigation_using_navigationlayers.rst 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. .. _doc_navigation_advanced_using_navigationlayers:
  2. Using NavigationLayers
  3. ======================
  4. NavigationLayers are an optional feature to further control which navigation meshes are considered in a path query and which regions can be connected.
  5. They work similar to how physics layers control collision between collision objects or how visual layers control what is rendered to the Viewport.
  6. NavigationLayers can be named in the ``ProjectSettings`` the same as PhysicsLayers or VisualLayers.
  7. .. image:: img/navigationlayers_naming.png
  8. If two regions have not a single compatible layer they will not be merged by the NavigationServer. See :ref:`doc_navigation_connecting_navmesh` for more information on merging navmesh.
  9. If a region has not a single compatible navigation layer with the ``navigation_layers`` parameter of a path query this regions navigation mesh will be skipped in pathfinding.
  10. See :ref:`doc_navigation_using_navigationpaths` for more information on querying the NavigationServer for paths.
  11. NavigationLayers are a single ``int`` value that is used as a ``bitmask``.
  12. Many navigation related nodes have ``set_navigation_layer_value()`` and
  13. ``get_navigation_layer_value()`` functions to set and get a layer number directly
  14. without the need for more complex bitwise operations.
  15. In scripts the following helper functions can be used to work with the navigation_layers bitmask.
  16. .. tabs::
  17. .. code-tab:: gdscript GDScript
  18. func change_layers():
  19. var region: NavigationRegion3D = get_node("NavigationRegion3D")
  20. # enables 4-th layer for this region
  21. region.navigation_layers = enable_bitmask_inx(region.navigation_layers, 4)
  22. # disables 1-rst layer for this region
  23. region.navigation_layers = disable_bitmask_inx(region.navigation_layers, 1)
  24. var agent: NavigationAgent3D = get_node("NavigationAgent3D")
  25. # make future path queries of this agent ignore regions with 4-th layer
  26. agent.navigation_layers = disable_bitmask_inx(agent.navigation_layers, 4)
  27. var path_query_navigation_layers: int = 0
  28. path_query_navigation_layers = enable_bitmask_inx(path_query_navigation_layers, 2)
  29. # get a path that only considers 2-nd layer regions
  30. var path: PoolVector3Array = NavigationServer3D.map_get_path(
  31. map,
  32. start_position,
  33. target_position,
  34. true,
  35. path_query_navigation_layers
  36. )
  37. static func is_bitmask_inx_enabled(_bitmask: int, _index: int) -> bool:
  38. return _bitmask & (1 << _index) != 0
  39. static func enable_bitmask_inx(_bitmask: int, _index: int) -> int:
  40. return _bitmask | (1 << _index)
  41. static func disable_bitmask_inx(_bitmask: int, _index: int) -> int:
  42. return _bitmask & ~(1 << _index)
  43. Changing navigation layers for path queries is a performance friendly alternative to
  44. enabling / disabling entire navigation regions. Compared to region changes a
  45. navigation path query with different navigation layers does not
  46. trigger large scale updates on the NavigationServer.
  47. Changing the navigation layers of NavigationAgent nodes will have an immediate
  48. effect on the next path query. Changing the navigation layers of
  49. regions will have an immediate effect on the region but any new region
  50. connect or disconnect will only be in effect after the next physics_frame.