2Dナビゲーション概要
Godot は2Dと3Dについて、様々なオブジェクト、クラス、そしてサーバーをグリッドベース、もしくはメッシュベースのナビゲーションと経路探索を容易にするために提供します。以下のセクションではGodotの2Dシーンで使用できるナビゲーション関連のオブジェクトとその用途についての簡単に概説します。
Godotは2Dナビゲーションのため、以下のオブジェクトとクラスを提供します:
- Astar2D
Astar2Dオブジェクトは、重み付き point のグラフの中で最短経路を見つけるオプションを提供します。Astar2D クラスは、エリア内の任意の位置に到達する必要がなく、あらかじめ定義された特定の位置にのみ到達するようなセルベースの2Dゲームプレイで最適です。
- AstarGrid2D
AstarGrid2Dis a variant of AStar2D that is specialized for partial 2D grids.AstarGrid2D is simpler to use when applicable because it doesn't require you to manually create points and connect them together.
- NavigationServer2D
NavigationServer2Dナビゲーションメッシュで定義されたエリア上で、2つの地点間の最短経路を見つけるための強力なAPIを提供します。NavigationServerは、ナビゲーションメッシュで定義されたエリア上で任意の地点に到達する必要があるような、2Dリアルタイムのゲームプレイに最も適しています。メッシュベースのナビゲーションは大きなゲームワールドでもよくスケールします。これは大きなエリアは非常に大量のグリッドセルを要求する場合でも、しばしば1つのポリゴンで定義されるためです。
NavigationServerは、複数のナビゲーションマップを管理しており、各マップはナビゲーションメッシュデータを保持する複数のリージョンで構成されています。回避計算のためにエージェントをマップ上に配置することができます。サーバーとの通信時には、内部のマップ、リージョン、およびエージェントを参照するために RIDが使用されます。
- 以下のNavigationServer RIDタイプが使用可能です。
- NavMap RID
リージョンやエージェントが含また特定のナビゲーションマップへの参照です。このマップは、リージョンのナビゲーションメッシュを近接性によって結合しようとします。マップは各物理フレームごとにリージョンとエージェントを同期します。
- NavRegion RID
Reference to a specific navigation region that can hold navigation mesh data. The region can be enabled / disabled or the use restricted with a navigation layer bitmask.
- NavLink RID
Reference to a specific navigation link that connects two navigation mesh positions over arbitrary distances.
- NavAgent RID
Reference to a specific avoidance agent. The avoidance is specified by a radius value.
- NavObstacle RID
Reference to a specific avoidance obstacle used to affect and constrain the avoidance velocity of agents.
The following scene tree nodes are available as helpers to work with the NavigationServer2D API.
- NavigationRegion2D Node
A Node that holds a NavigationPolygon resource that defines a navigation mesh for the NavigationServer2D.
The region can be enabled / disabled.
The use in pathfinding can be further restricted through the
navigation_layersbitmask.The NavigationServer2D will join the navigation meshes of regions by proximity for a combined navigation mesh.
- NavigationLink2D Node
A Node that connects two positions on navigation meshes over arbitrary distances for pathfinding.
The link can be enabled / disabled.
The link can be made one-way or bidirectional.
The use in pathfinding can be further restricted through the
navigation_layersbitmask.
Links tell the pathfinding that a connection exists and at what cost. The actual agent handling and movement needs to happen in custom scripts.
- NavigationAgent2D Node
A helper Node used to facilitate common NavigationServer2D API calls for pathfinding and avoidance. Use this Node with a Node2D inheriting parent Node.
- NavigationObstacle2D Node
A Node that can be used to affect and constrain the avoidance velocity of avoidance enabled agents. This Node does NOT affect the pathfinding of agents. You need to change the navigation meshes for that instead.
The 2D navigation meshes are defined with the following resources:
- NavigationPolygon Resource
A resource that holds 2D navigation mesh data. It provides polygon drawing tools to allow defining navigation areas inside the Editor as well as at runtime.
The NavigationRegion2D Node uses this resource to define its navigation area.
The NavigationServer2D uses this resource to update the navigation mesh of individual regions.
The TileSet Editor creates and uses this resource internally when defining tile navigation areas.
参考
You can see how 2D navigation works in action using the 2D Navigation Polygon and Grid-based Navigation with AStarGrid2D demo projects.
Setup for 2D scene
The following steps show the basic setup for minimal viable navigation in 2D. It uses the NavigationServer2D and a NavigationAgent2D for path movement.
Add a NavigationRegion2D Node to the scene.
Click on the region node and add a new NavigationPolygon Resource to the region node.
Define the movable navigation area with the NavigationPolygon draw tool. Then click the Bake NavigationPolygon button on the toolbar.
注釈
The navigation mesh defines the area where an actor can stand and move with its center. Leave enough margin between the navigation polygon edges and collision objects to not get path following actors repeatedly stuck on collision.
Add a CharacterBody2D node in the scene with a basic collision shape and a sprite or mesh for visuals.
Add a NavigationAgent2D node below the character node.
Add the following script to the CharacterBody2D node. We make sure to set a movement target after the scene has fully loaded and the NavigationServer had time to sync.
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;
}
}
注釈
On the first frame the NavigationServer map has not synchronized region data and any path query will return empty. Wait for the NavigationServer synchronization by awaiting one frame in the script.