Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Огляд двовимірної навігації
Godot надає численні об’єкти, класи та сервери для спрощення навігації на основі сітки або сітки та пошуку шляху для 2D та 3D ігор. У наступному розділі наведено короткий огляд усіх доступних навігаційних об’єктів у Godot для 2D-сцен та їх основного використання.
Godot надає такі об’єкти та класи для двовимірної навігації:
- Astar2D
Об’єкти
Astar2Dнадають можливість знайти найкоротший шлях у графіку зважених точок.Клас AStar2D найкраще підходить для двовимірного геймплея на основі клітинок, який не вимагає від акторів досягнення будь-якої можливої позиції в межах області, а лише попередньо визначених, чітких позицій.
- AstarGrid2D
AstarGrid2D— це варіант AStar2D, який спеціалізується на часткових 2D сітках.AstarGrid2D простіше у використанні, якщо це можливо, оскільки не вимагає вручну створювати точки та з’єднувати їх разом.
- NavigationServer2D
NavigationServer2Dнадає потужний серверний API для пошуку найкоротшого шляху між двома позиціями в області, визначеній навігаційною сіткою.NavigationServer найкраще підходить для двовимірної гри в реальному часі, яка вимагає від акторів досягнення будь-якої можливої позиції в межах визначеної навігаційною сіткою області. Навігація на основі сітки добре масштабується з великими ігровими світами, оскільки велику територію часто можна визначити за допомогою одного багатокутника, коли для цього потрібно багато, багато комірок сітки.
NavigationServer містить різні навігаційні карти, кожна з яких складається з регіонів, які містять дані навігаційної сітки. Агентів можна розмістити на карті для розрахунку уникнення. RID використовуються для посилань на внутрішні карти, регіони та агентів під час обміну даними із сервером.
- Доступні наступні типи RID NavigationServer.
- NavMap RID
Посилання на конкретну навігаційну карту, яка містить регіони та агентів. Карта намагатиметься приєднатися до навігаційних сіток регіонів за віддаленістю. Карта синхронізуватиме регіони та агентів у кожному кадрі фізики.
- NavRegion RID
Посилання на певну область навігації, яка може містити дані сітки навігації. Регіон можна ввімкнути/вимкнути або обмежити використання за допомогою бітової маски шару навігації.
- NavLink RID
Посилання на конкретне навігаційне посилання, яке з’єднує дві позиції навігаційної сітки на довільних відстанях.
- NavAgent RID
Посилання на конкретного агента уникнення. Уникнення визначається значенням радіуса.
- NavObstacle RID
Посилання на конкретну перешкоду для уникнення, що використовується для впливу та обмеження швидкості уникнення агентів.
Наступні вузли дерева сцен доступні як допоміжні для роботи з NavigationServer2D API.
- NavigationRegion2D Node
Вузол, який містить ресурс NavigationPolygon, який визначає навігаційну сітку для NavigationServer2D.
Регіон можна включити / вимкнути.
Використання для пошуку шляху може бути додатково обмежено за допомогою бітової маски
navigation_layers.NavigationServer2D об’єднає навігаційні сітки регіонів за близькістю для комбінованої навігаційної сітки.
- NavigationLink2D Node
Вузол, який з’єднує дві позиції на навігаційних сітках на довільних відстанях для пошуку шляху.
Посилання можна включити/вимкнути.
Посилання можна зробити одностороннім або двонаправленим.
Використання для пошуку шляху може бути додатково обмежено за допомогою бітової маски
navigation_layers.
Посилання повідомляють досліднику про те, що зв’язок існує та якою ціною. Фактична обробка та переміщення агента має відбуватися в спеціальних сценаріях.
- NavigationAgent2D Node
Допоміжний вузол, який використовується для полегшення загальних викликів API NavigationServer2D для пошуку та уникнення. Використовуйте цей вузол із успадкованим батьківським вузлом Node2D.
- NavigationObstacle2D Node
Вузол, який можна використовувати для впливу та обмеження швидкості уникнення агентів із увімкненим уникненням. Цей вузол НЕ впливає на пошук шляхів агентів. Для цього вам потрібно змінити навігаційні сітки.
Двовимірні навігаційні сітки визначаються за допомогою таких ресурсів:
- NavigationPolygon Resource
Ресурс, який містить дані двовимірної навігаційної сітки. Він надає інструменти малювання багатокутників, які дозволяють визначати області навігації в редакторі, а також під час виконання.
Вузол NavigationRegion2D використовує цей ресурс для визначення своєї області навігації.
NavigationServer2D використовує цей ресурс для оновлення сітки навігації окремих регіонів.
TileSet Editor створює та використовує цей ресурс усередині під час визначення областей навігації плиток.
Дивись також
Ви можете побачити, як 2D-навігація працює в дії, використовуючи 2D Navigation Polygon та Grid-based Navigation with AStarGrid2D демонстраційні проекти.
Налаштування для 2D сцени
Наступні кроки показують базове налаштування для мінімальної життєздатної навігації у 2D. Він використовує NavigationServer2D і NavigationAgent2D для переміщення шляху.
Додайте до сцени вузол NavigationRegion2D.
Клацніть вузол регіону та додайте новий ресурс NavigationPolygon до вузла регіону.
Визначте рухому область навігації за допомогою інструмента малювання «Навігаційний полігон». Потім натисніть кнопку Bake NavigationPolygon на панелі інструментів.
Примітка
Навігаційна сітка визначає область, де актор може стояти та рухатися за допомогою свого центру. Залиште достатню межу між краями навігаційного багатокутника та об’єктами зіткнення, щоб актори, що слідують за шляхом, неодноразово застрягали під час зіткнення.
Додайте вузол CharacterBody2D у сцену з основною формою зіткнення та спрайтом або сіткою для візуальних ефектів.
Додайте вузол NavigationAgent2D під вузлом символів.
Додайте наступний скрипт до вузла CharacterBody2D. Ми обов’язково встановлюємо ціль переміщення після того, як сцена повністю завантажилась і NavigationServer мав час для синхронізації.
extends CharacterBody2D
var movement_speed: float = 200.0
var movement_target_position: Vector2 = Vector2(60.0,180.0)
@onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D
func _ready():
# These values need to be adjusted for the actor's speed
# and the navigation layout.
navigation_agent.path_desired_distance = 4.0
navigation_agent.target_desired_distance = 4.0
# 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: Vector2):
navigation_agent.target_position = movement_target
func _physics_process(delta):
if navigation_agent.is_navigation_finished():
return
var current_agent_position: Vector2 = global_position
var next_path_position: Vector2 = navigation_agent.get_next_path_position()
velocity = current_agent_position.direction_to(next_path_position) * movement_speed
move_and_slide()
using Godot;
public partial class MyCharacterBody2D : CharacterBody2D
{
private NavigationAgent2D _navigationAgent;
private float _movementSpeed = 200.0f;
private Vector2 _movementTargetPosition = new Vector2(70.0f, 226.0f);
public Vector2 MovementTarget
{
get { return _navigationAgent.TargetPosition; }
set { _navigationAgent.TargetPosition = value; }
}
public override void _Ready()
{
base._Ready();
_navigationAgent = GetNode<NavigationAgent2D>("NavigationAgent2D");
// These values need to be adjusted for the actor's speed
// and the navigation layout.
_navigationAgent.PathDesiredDistance = 4.0f;
_navigationAgent.TargetDesiredDistance = 4.0f;
// Make sure to not await during _Ready.
Callable.From(ActorSetup).CallDeferred();
}
public override void _PhysicsProcess(double delta)
{
base._PhysicsProcess(delta);
if (_navigationAgent.IsNavigationFinished())
{
return;
}
Vector2 currentAgentPosition = GlobalTransform.Origin;
Vector2 nextPathPosition = _navigationAgent.GetNextPathPosition();
Velocity = currentAgentPosition.DirectionTo(nextPathPosition) * _movementSpeed;
MoveAndSlide();
}
private async void ActorSetup()
{
// Wait for the first physics frame so the NavigationServer can sync.
await ToSignal(GetTree(), SceneTree.SignalName.PhysicsFrame);
// Now that the navigation map is no longer empty, set the movement target.
MovementTarget = _movementTargetPosition;
}
}
Примітка
У першому кадрі карта NavigationServer не синхронізувала дані регіону, і будь-який запит шляху буде порожнім. Зачекайте на синхронізацію NavigationServer, дочекавшись одного кадру в сценарії.