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...
Visão geral de navegação 2D
O Godot fornece múltiplos objetos, classes e servidores para facilitar a navegação baseada em grades ou malhas e a busca de caminhos (pathfinding) para jogos 2D e 3D. A seção a seguir fornece uma visão geral rápida de todos os objetos relacionados à navegação disponíveis no Godot para cenas 2D e seu uso principal.
O Godot fornece os seguintes objetos e classes para navegação 2D:
- Astar2D
Objetos
Astar2Dfornecem uma opção para encontrar o caminho mais curto em um grafo de pontos ponderados.A classe AStar2D é mais adequada para jogabilidade 2D baseada em células que não exige que os atores alcancem qualquer posição possível dentro de uma área, mas apenas posições predefinidas e distintas.
- AstarGrid2D
AstarGrid2Dé uma variante do AStar2D especializada para grades 2D parciais.O AstarGrid2D é mais simples de usar quando aplicável porque não exige que você crie pontos manualmente e os conecte.
- NavigationServer2D
O
NavigationServer2Dfornece uma poderosa API de servidor para encontrar o caminho mais curto entre duas posições em uma área definida por uma malha de navegação (navigation mesh).O NavigationServer é mais adequado para jogabilidade 2D em tempo real que exige que os atores alcancem qualquer posição possível dentro de uma área definida por uma malha de navegação. A navegação baseada em malhas escala bem com grandes mundos de jogo, pois uma grande área geralmente pode ser definida com um único polígono, quando exigiria muitas e muitas células de grade.
O NavigationServer possui mapas de navegação diferentes, cada um composto por regiões que contêm dados de malha de navegação. Os agentes podem ser colocados em um mapa para o cálculo de desvio (avoidance). RIDs são usados para referenciar mapas internos, regiões e agentes ao se comunicar com o servidor.
- Os seguintes tipos de RID do NavigationServer estão disponíveis.
- RID do NavMap
Referência a um mapa de navegação específico que contém regiões e agentes. O mapa tentará unir as malhas de navegação das regiões por proximidade. O mapa sincronizará as regiões e os agentes a cada quadro de física.
- RID da NavRegion
Referência a uma região de navegação específica que pode conter dados de malha de navegação. A região pode ser ativada/desativada ou ter seu uso restrito com uma máscara de bits de camada de navegação (navigation layer bitmask).
- RID do NavLink
Referência a um link de navegação específico que conecta duas posições de malha de navegação ao longo de distâncias arbitrárias.
- RID do NavAgent
Referência a um agente de desvio específico. O desvio é especificado por um valor de raio.
- RID de NavObstacle
Referência a um obstáculo de desvio específico usado para afetar e restringir a velocidade de desvio dos agentes.
Os seguintes nós da árvore de cenas estão disponíveis como auxiliares para trabalhar com a API do NavigationServer2D.
- Nó NavigationRegion2D
Um Nó que contém um recurso NavigationPolygon que define uma malha de navegação para o NavigationServer2D.
A região pode ser ativada / desativada.
O uso na busca de caminhos pode ser ainda mais restrito através da máscara de bits
navigation_layers.O NavigationServer2D unirá as malhas de navegação das regiões por proximidade para formar uma malha de navegação combinada.
- Nó NavigationLink2D
Um Nó que conecta duas posições em malhas de navegação ao longo de distâncias arbitrárias para a busca de caminhos.
O link pode ser ativado / desativado.
O link pode ser configurado como de mão única (one-way) ou bidirecional.
O uso na busca de caminhos pode ser ainda mais restrito através da máscara de bits
navigation_layers.
Os links informam à busca de caminhos que existe uma conexão e com qual custo. A manipulação e o movimento reais do agente precisam acontecer em scripts personalizados.
- Nó NavigationAgent2D
Um Nó auxiliar usado para facilitar chamadas comuns da API do NavigationServer2D para busca de caminhos e desvio. Use este Nó com um Nó pai que herde de Node2D.
- Nó NavigationObstacle2D
Um Nó que pode ser usado para afetar e restringir a velocidade de desvio de agentes com o desvio ativado. Este Nó NÃO afeta a busca de caminhos dos agentes. Em vez disso, você precisa alterar as malhas de navegação para isso.
As malhas de navegação 2D são definidas com as seguintes recursos:
- Recurso NavigationPolygon
Um recurso que contém dados de malha de navegação 2D. Ele fornece ferramentas de desenho de polígonos para permitir a definição de áreas de navegação dentro do Editor, bem como em tempo de execução.
O Nó NavigationRegion2D usa este recurso para definir sua área de navegação.
O NavigationServer2D usa este recurso para atualizar a malha de navegação de regiões individuais.
O Editor de TileSet cria e usa este recurso internamente ao definir áreas de navegação de tiles.
Ver também
Você pode ver como a navegação 2D funciona em ação usando os projetos de demonstração 2D Navigation Polygon e Grid-based Navigation with AStarGrid2D.
Configuração para cena 2D
Os passos a seguir mostram a configuração básica para uma navegação mínima viável em 2D. Ela usa o NavigationServer2D e um NavigationAgent2D para o movimento pelo caminho.
Adicione um Nó NavigationRegion2D à cena.
Clique no nó da região e adicione um novo Recurso NavigationPolygon ao nó da região.
Defina a área de navegação móvel com a ferramenta de desenho do NavigationPolygon. Em seguida, clique no botão Bake NavigationPolygon na barra de ferramentas.
Nota
A malha de navegação define a área onde um ator pode ficar de pé e se mover com o seu centro. Deixe uma margem suficiente entre as bordas do polígono de navegação e os objetos de colisão para que os atores que seguem o caminho não fiquem travados repetidamente na colisão.
Adicione um nó CharacterBody2D na cena com uma forma de colisão básica e um sprite ou mesh para o visual.
Adicione um nó NavigationAgent2D abaixo do nó do personagem.
Adicione o seguinte script ao nó CharacterBody2D. Certificamo-nos de definir um alvo de movimento após a cena ter sido totalmente carregada e o NavigationServer ter tido tempo de sincronizar.
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;
}
}
Nota
No primeiro quadro, o mapa do NavigationServer não sincronizou os dados da região e qualquer consulta de caminho retornará vazia. Aguarde a sincronização do NavigationServer esperando um quadro no script.