Обзор 3D-навигации

Godot предоставляет множество объектов, классов и серверов для упрощения навигации и поиска пути на основе сетки или сетки в 2D- и 3D-играх. В следующем разделе представлен краткий обзор всех доступных объектов навигации в Godot для 3D-сцен и их основных применений.

Godot предоставляет следующие объекты и классы для 3D-навигации:

  • Astar3D

    Astar3D объекты предоставляют возможность найти кратчайший путь в графе взвешенных points (точек).

    Класс AStar3D лучше всего подходит для 3D-игры на основе ячеек, в которой от актеров не требуется достигать какой-либо возможной позиции в области, а только предопределенных, отдельных позиций.

  • NavigationServer3D

    NavigationServer3D предоставляет мощный серверный API для поиска кратчайшего пути между двумя позициями на территории, определенной навигационной сеткой.

    NavigationServer лучше всего подходит для трёхмерного игрового процесса в реальном времени, требующего от актёров достижения любой возможной позиции в области, заданной навигационной сеткой. Навигация на основе сетки хорошо масштабируется в больших игровых мирах, поскольку большую область часто можно определить одним полигоном, тогда как для этого потребовалось бы множество ячеек сетки.

    NavigationServer хранит различные навигационные карты, каждая из которых состоит из регионов с данными навигационной сетки. Агенты могут быть размещены на карте для расчета маршрутов избегания столкновений. Идентификаторы RID используются для ссылки на внутренние карты, регионы и агентов при взаимодействии с сервером.

    Доступны следующие типы RID NavigationServer.
    • NavMap RID ((Навигационная карта RID)

      Ссылка на конкретную навигационную карту, содержащую регионы и агентов. Карта будет пытаться объединить навигационные сетки регионов по близости. Карта будет синхронизировать регионы и агентов в каждом физическом кадре.

    • NavRegion RID (Навигационный регион RID)

      Ссылка на конкретную навигационную область, которая может содержать данные навигационной сетки. Область можно включить/отключить или ограничить её использование с помощью битовой маски навигационного слоя.

    • NavLink RID (Навигационная ссылка RID)

      Ссылка на конкретную навигационную ссылку, которая соединяет две позиции навигационной сетки на произвольных расстояниях.

    • NavAgent RID (Навигационный агент RID)

      Ссылка на конкретный агент избегания. Избегание определяется значением радиуса.

    • NavObstacle RID

      Ссылка на конкретное препятствие избегания, используемое для воздействия и ограничения скорости избегания агентов.

Следующие узлы дерева сцены доступны в качестве вспомогательных средств для работы с API NavigationServer3D.

  • Узел NavigationRegion3D

    Узел, содержащий ресурс Navigation Mesh (навигационной сетки,) который определяет навигационную сетку для NavigationServer3D.

    • Регион можно включить/отключить.

    • Использование при поиске пути можно дополнительно ограничить с помощью битовой маски navigation_layers.

    • NavigationServer3D объединит навигационные сетки регионов по близости для создания объединенной навигационной сетки.

  • Узел NavigationLink3D

    Узел, соединяющий две позиции на навигационных сетках на произвольных расстояниях для поиска пути.

    • Ссылку можно включить/отключить.

    • Связь может быть односторонней или двунаправленной.

    • Использование при поиске пути можно дополнительно ограничить с помощью битовой маски navigation_layers.

    Ссылки сообщают системе поиска пути о наличии соединения и его стоимости. Фактическое управление агентом и его перемещение должны осуществляться в специальных скриптах.

  • Узел NavigationAgent3D

    Вспомогательный Узел, используемый для упрощения выполнения общих вызовов API NavigationServer3D для поиска пути и обхода препятствий. Используйте этот Node с узлом Node3D, наследующим родительский узел.

  • Узел NavigationObstacle3D

    Узел, который можно использовать для управления и ограничения скорости уклонения агентов с включенной функцией уклонения. Этот узел НЕ влияет на поиск пути агентами. Для этого необходимо изменить навигационные сетки.

3D-сетки навигации определяются с помощью следующих ресурсов:

  • Ресурс NavigationMesh

    Ресурс, содержащий данные 3D-сетки навигации. Он предоставляет возможности запекания 3D-геометрии для определения областей навигации как в Редакторе, так и во время выполнения.

    • Узел NavigationRegion3D использует этот ресурс для определения своей области навигации.

    • NavigationServer3D использует этот ресурс для обновления навигационной сетки отдельных регионов.

    • Редактор GridMap использует этот ресурс, когда для каждой ячейки сетки определяются конкретные навигационные сетки.

См. также

Вы можете увидеть, как работает 3D-навигация в действии, используя 3D Navigation demo project.

Настройка для 3D-сцены

Следующие шаги демонстрируют базовую настройку минимально жизнеспособной навигации в 3D. Она использует NavigationServer3D и NavigationAgent3D для перемещения по траектории.

  1. Добавьте к сцене узел NavigationRegion3D.

  2. Щелкните узел региона и добавьте новый ресурс NavigationMesh к узлу региона.

    ../../_images/nav_3d_min_setup_step1.png
  3. Добавьте новый узел MeshInstance3D как дочерний узел узла региона.

  4. Выберите узел MeshInstance3D и добавьте новый PlaneMesh, а затем увеличьте размер xy до 10.

  5. Снова выберите узел региона и нажмите кнопку "Bake Navmesh" на верхней панели.

    ../../_images/nav_3d_min_setup_step2.png
  6. Теперь появляется прозрачная навигационная сетка, которая парит на некотором расстоянии над PlaneMesh.

    ../../_images/nav_3d_min_setup_step3.png
  7. Добавьте в сцену узел CharacterBody3D с базовой формой столкновения и сеткой для визуализации.

  8. Добавьте узел NavigationAgent3D под узлом персонажа.

    ../../_images/nav_3d_min_setup_step4.webp
  9. Добавьте скрипт к узлу CharacterBody3D со следующим содержимым. Мы обязательно задаём цель движения после полной загрузки сцены и синхронизации NavigationServer. Также добавим Camera3D, освещение и окружение, чтобы что-то было видно.

extends CharacterBody3D

var movement_speed: float = 2.0
var movement_target_position: Vector3 = Vector3(-3.0,0.0,2.0)

@onready var navigation_agent: NavigationAgent3D = $NavigationAgent3D

func _ready():
    # These values need to be adjusted for the actor's speed
    # and the navigation layout.
    navigation_agent.path_desired_distance = 0.5
    navigation_agent.target_desired_distance = 0.5

    # Make sure to not await during _ready.
    actor_setup.call_deferred()

func actor_setup():
    # Wait for the first physics frame so the NavigationServer can sync.
    await get_tree().physics_frame

    # Now that the navigation map is no longer empty, set the movement target.
    set_movement_target(movement_target_position)

func set_movement_target(movement_target: Vector3):
    navigation_agent.set_target_position(movement_target)

func _physics_process(delta):
    if navigation_agent.is_navigation_finished():
        return

    var current_agent_position: Vector3 = global_position
    var next_path_position: Vector3 = navigation_agent.get_next_path_position()

    velocity = current_agent_position.direction_to(next_path_position) * movement_speed
    move_and_slide()

Примечание

В первом кадре карта NavigationServer не синхронизировала данные региона, и любой запрос пути вернёт пустой. Дождитесь синхронизации NavigationServer, подождав один кадр в скрипте.