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 게임에 대한 그리드 기반 또는 메시 기반 탐색 및 경로 찾기를 용이하게 하기 위해 여러 개체, 클래스 및 서버를 제공합니다. 다음 섹션은 2D 장면을 위해 Godot에서 사용 가능한 모든 탐색 관련 객체와 그 주요 용도에 대한 빠른 개요를 제공합니다.
Godot는 다음 3D 씬 파일 형식을 지원합니다:
- Area2D
Astar2D개체는 가중치 점 그래프에서 최단 경로를 찾는 옵션을 제공합니다.AStar2D 클래스는 액터가 영역 내의 가능한 위치에 도달할 필요가 없고 미리 정의된 고유한 위치에만 도달하도록 요구하는 셀 기반 2D 게임플레이에 가장 적합합니다.
- String
``NavigationServer2D``는 탐색 메시로 정의된 영역에서 두 위치 사이의 최단 경로를 찾는 강력한 서버 API를 제공합니다.
NavigationServer는 액터가 정의된 내비게이션 메시 영역 내에서 가능한 모든 위치에 도달해야 하는 2D 실시간 게임플레이에 가장 적합합니다. 메쉬 기반 내비게이션은 대규모 게임 세계에 맞게 확장됩니다. 많은 그리드 셀이 필요한 경우 단일 다각형으로 넓은 영역을 정의할 수 있는 경우가 많기 때문입니다.
NavigationServer는 각각 탐색 메시 데이터를 보유하는 영역으로 구성된 다양한 탐색 맵을 보유합니다. 회피 계산을 위해 에이전트를 지도에 배치할 수 있습니다. RID는 서버와 통신할 때 내부 지도, 지역 및 에이전트를 참조하는 데 사용됩니다.
- 다음 NavigationServer RID 유형을 사용할 수 있습니다.
- NavMap RID
지역과 에이전트가 포함된 특정 탐색 지도에 대한 참조입니다. 지도는 근접성을 기준으로 지역의 내비게이션 메시를 결합하려고 시도합니다. 맵은 각 물리 프레임마다 지역과 에이전트를 동기화합니다.
- Nav지역 RID
탐색 메시 데이터를 보유할 수 있는 특정 탐색 영역에 대한 참조입니다. 탐색 레이어 비트마스크를 사용하여 영역을 활성화/비활성화하거나 사용을 제한할 수 있습니다.
- NavLink RID
임의의 거리에 걸쳐 두 개의 탐색 메시 위치를 연결하는 특정 탐색 링크에 대한 참조입니다.
- NavAgent RID
특정 회피 행위자에 대한 언급. 회피는 반경 값으로 지정됩니다.
- 내비게이션
에이전트의 회피 속도에 영향을 미치고 제한하는 데 사용되는 특정 회피 장애물에 대한 참조입니다.
다음 씬 트리 노드는 NavigationServer2D API 작업을 위한 도우미로 사용할 수 있습니다.
- String
NavigationServer2D에 대한 탐색 메시를 정의하는 NavigationPolygon 리소스를 보유하는 노드입니다.
지역을 활성화/비활성화할 수 있습니다.
경로 찾기에서의 사용은
navigation_layers비트마스크를 통해 추가로 제한될 수 있습니다.NavigationServer2D는 결합된 탐색 메시에 대한 근접성을 기준으로 영역의 탐색 메시를 결합합니다.
- String
길 찾기를 위해 임의의 거리에 걸쳐 탐색 메시의 두 위치를 연결하는 노드입니다.
링크를 활성화/비활성화할 수 있습니다.
링크는 단방향 또는 양방향으로 이루어질 수 있습니다.
경로 찾기에서의 사용은
navigation_layers비트마스크를 통해 추가로 제한될 수 있습니다.
링크는 연결이 존재하고 비용이 얼마나 드는지 길찾기에 알려줍니다. 실제 에이전트 처리 및 이동은 사용자 정의 스크립트에서 이루어져야 합니다.
- String
경로 찾기 및 회피를 위한 일반적인 NavigationServer2D API 호출을 용이하게 하는 데 사용되는 도우미 노드입니다. 이 노드를 Node2D 상속 상위 노드와 함께 사용하세요.
- Dictionary
회피 가능 에이전트의 회피 속도에 영향을 미치고 제한하는 데 사용할 수 있는 노드입니다. 이 노드는 에이전트의 경로 찾기에 영향을 주지 않습니다. 대신 탐색 메시를 변경해야 합니다.
적 씬은 다음 노드들을 사용할 것입니다:
- String
2D 탐색 메시 데이터를 보유하는 리소스입니다. 이는 런타임뿐만 아니라 편집기 내에서 탐색 영역을 정의할 수 있는 다각형 그리기 도구를 제공합니다.
NavigationRegion2D 노드는 이 리소스를 사용하여 탐색 영역을 정의합니다.
NavigationServer2D는 이 리소스를 사용하여 개별 영역의 탐색 메시를 업데이트합니다.
TileSet Editor는 타일 탐색 영역을 정의할 때 내부적으로 이 리소스를 생성하고 사용합니다.
더 보기
2D Navigation Polygon 및 Grid-based Navigation with AStarGrid2D 데모 프로젝트를 사용하여 2D 네비게이션이 실제로 어떻게 작동하는지 확인할 수 있습니다.
씬 설정하기
다음 단계에서는 2D에서 최소한의 실행 가능한 탐색을 위한 기본 설정을 보여줍니다. 경로 이동을 위해 NavigationServer2D 및 NavigationAgent2D를 사용합니다.
씬에 NavigationRegion2D 노드를 추가합니다.
노드 지역을 클릭하고 노드 지역에 새 NavigationPolygon 리소스를 추가합니다.
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 동기화를 기다립니다.