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...
내비게이션 메시.
내비게이션 메시의 2D 및 3D 버전은 각각 NavigationPolygon 및 :ref:`NavigationMesh<class_NavigationMesh>`로 제공됩니다.
참고
탐색 메시는 에이전트의 중앙 위치에 대한 이동 가능한 영역만 설명합니다. 에이전트가 가질 수 있는 반경 값은 무시됩니다. 에이전트의 (충돌) 크기를 설명하기 위해 경로 찾기를 원하는 경우 그에 따라 탐색 메시를 축소해야 합니다.
내비게이션은 렌더링이나 물리 같은 다른 엔진 부품과 독립적으로 작동합니다. 내비게이션 메시는 길 찾기를 수행할 때 고려되는 유일한 사항입니다. 예를 들어 내비게이션 시스템에서는 시각적 및 충돌 모양이 완전히 무시됩니다. 길 찾기를 수행할 때 다른 데이터(예: 시각적 요소)를 고려해야 하는 경우 그에 따라 탐색 메시를 조정해야 합니다. 탐색 메시의 탐색 제한 사항을 고려하는 프로세스를 일반적으로 탐색 메시 베이킹이라고 합니다.
내비게이션 메시는 외부 충돌 경계를 설명하는 물리 모양과 비교하여 에이전트가 중앙에 안전하게 서 있을 수 있는 표면을 설명합니다.
탐색 경로를 따라가는 동안 클리핑이나 충돌 문제가 발생하는 경우 적절한 탐색 메시를 통해 내비게이션 시스템에 의도를 알려야 한다는 점을 항상 기억하세요. 자체적으로 내비게이션 시스템은 "이것이 나무/바위/벽 충돌 모양 또는 시각적 메시입니다"를 결코 알 수 없습니다. 왜냐하면 "여기서는 내비게이션 메시에 있기 때문에 안전하게 경로를 지정할 수 있다고 들었습니다"라는 것만 알고 있기 때문입니다.
탐색 메시 베이킹은 NavigationRegion2D 또는 NavigationRegion3D 및 NavigationServer3D API를 직접 사용하여 수행할 수 있습니다.
NavigationRegion을 사용하여 탐색 메시 굽기
지오메트리에서 에이전트 반경 오프셋을 사용하여 탐색 메시를 굽습니다.
NavigationRegion 노드를 사용하면 탐색 메시 베이킹에 더 쉽게 액세스할 수 있습니다. NavigationRegion 노드를 사용하여 베이킹하는 경우 개별 구문 분석, 베이킹 및 영역 업데이트 단계가 모두 하나의 기능으로 결합됩니다.
노드는 각각 NavigationRegion2D 및 :ref:`NavigationRegion3D<class_NavigationRegion3D>`로 2D 및 3D로 제공됩니다.
팁
탐색 메시 ``source_geometry_mode``를 전환하여 특정 노드 그룹 이름을 구문 분석할 수 있으므로 구워야 하는 노드를 씬의 어느 곳에나 배치할 수 있습니다.
Editor에서 NavigationRegion2D 노드를 선택하면 베이킹 옵션과 다각형 그리기 도구가 편집기 상단 표시줄에 나타납니다.
탐색 메시를 구문 분석하고 굽는 속성은 사용된 리소스의 일부가 되며 리소스 인스펙터에서 찾을 수 있습니다.
적 씬은 다음 노드들을 사용할 것입니다:
시각적 개체나 물리적 개체 또는 둘 다를 필터링하는 ``parsed_geometry_type``는 :ref:`SceneTree<class_SceneTree>`에서 구문 분석되어야 합니다. 어떤 객체가 어떻게 구문 분석되는지에 대한 자세한 내용은 아래 소스 형상 구문 분석 섹션을 참조하세요.
``collision_mask``는 ``parsed_geometry_type``에 정적 충돌체가 포함된 경우 물리 충돌 개체가 포함되는 필터입니다.
구문 분석을 시작할 노드와 :ref:`SceneTree<class_SceneTree>`를 통과하는 방법을 정의하는 ``source_geometry_mode``입니다.
``source_geometry_group_name``는 특정 노드 그룹만 구문 분석해야 하는 경우에 사용됩니다. 선택한 ``source_geometry_mode``에 따라 다릅니다.
적 씬은 다음 노드들을 사용할 것입니다:
``cell_size``는 래스터화 그리드 크기를 설정하며 내비게이션 지도 크기와 일치해야 합니다.
``agent_radius``는 에이전트(충돌) 크기에 충분한 여유를 갖도록 구운 탐색 메시를 축소합니다.
NavigationRegion2D 베이킹은 런타임 시 스크립트와 함께 사용할 수도 있습니다.
var on_thread: bool = true
bake_navigation_polygon(on_thread)
bool onThread = true;
BakeNavigationPolygon(onThread);
기본 설정으로 2D 베이킹을 빠르게 테스트하려면:
NavigationRegion2D 아래에 :ref:`Polygon2D<class_Polygon2D>`를 추가합니다.
선택한 NavigationRegion2D 그리기 도구를 사용하여 1개의 NavigationPolygon 윤곽선을 그립니다.
선택한 Polygon2D 그리기 도구를 사용하여 NavigationPolygon 윤곽선 내부에 1개의 Polygon2D 윤곽선을 그립니다.
Editor Bake 버튼을 누르면 탐색 메시가 나타납니다.
Editor에서 NavigationRegion3D 노드를 선택하면 베이킹 옵션이 Editor의 상단 표시줄에 나타납니다.
탐색 메시를 구문 분석하고 굽는 속성은 사용된 리소스의 일부가 되며 리소스 인스펙터에서 찾을 수 있습니다.
적 씬은 다음 노드들을 사용할 것입니다:
시각적 개체나 물리적 개체 또는 둘 다를 필터링하는 ``parsed_geometry_type``는 :ref:`SceneTree<class_SceneTree>`에서 구문 분석되어야 합니다. 어떤 객체가 어떻게 구문 분석되는지에 대한 자세한 내용은 아래 소스 형상 구문 분석 섹션을 참조하세요.
``collision_mask``는 ``parsed_geometry_type``에 정적 충돌체가 포함된 경우 물리 충돌 개체가 포함되는 필터입니다.
구문 분석을 시작할 노드와 :ref:`SceneTree<class_SceneTree>`를 통과하는 방법을 정의하는 ``source_geometry_mode``입니다.
``source_geometry_group_name``는 특정 노드 그룹만 구문 분석해야 하는 경우에 사용됩니다. 선택한 ``source_geometry_mode``에 따라 다릅니다.
적 씬은 다음 노드들을 사용할 것입니다:
cell_size및 ``cell_height``는 래스터화 복셀 그리드 크기를 설정하고 내비게이션 지도 크기와 일치해야 합니다.``agent_radius``는 에이전트(충돌) 크기에 충분한 여유를 갖도록 구운 탐색 메시를 축소합니다.
``agent_height``는 에이전트의 키가 너무 커서 들어갈 수 없는 탐색 메시 영역을 제외합니다.
agent_max_climb및 ``agent_max_slope``는 인접한 복셀 간의 높이 차이가 너무 크거나 표면이 너무 가파른 영역을 제거합니다.
경고
너무 작은 cell_size 또는 ``cell_height``는 너무 많은 복셀을 생성하여 게임이 멈추거나 심지어 충돌할 가능성이 있습니다.
NavigationRegion3D 베이킹은 런타임에 스크립트와 함께 사용할 수도 있습니다.
var on_thread: bool = true
bake_navigation_mesh(on_thread)
bool onThread = true;
BakeNavigationMesh(onThread);
기본 설정으로 3D 베이킹을 빠르게 테스트하려면:
NavigationRegion3D 아래에 :ref:`MeshInstance3D<class_MeshInstance3D>`를 추가합니다.
MeshInstance3D에 :ref:`PlaneMesh<class_PlaneMesh>`를 추가합니다.
Editor Bake 버튼을 누르면 탐색 메시가 나타납니다.
다른 스크립팅 언어와 소통하기
NavigationServer2D 및 :ref:`NavigationServer3D<class_NavigationServer3D>`에는 탐색 메시 베이킹 프로세스의 각 단계를 개별적으로 호출하는 API 기능이 있습니다.
``parse_source_geometry_data()``를 사용하면 소스 형상을 재사용 가능하고 직렬화 가능한 리소스로 구문 분석할 수 있습니다.
``bake_from_source_geometry_data()``는 이미 구문 분석된 데이터에서 탐색 메시를 굽는 데 사용할 수 있습니다. (중복) 구문 분석으로 인한 런타임 성능 문제를 방지합니다.
``bake_from_source_geometry_data_async()``는 동일하지만 메인 스레드를 차단하지 않고 스레드로 지연된 탐색 메시를 굽습니다.
NavigationRegion과 비교하여 NavigationServer는 탐색 메시 베이킹 프로세스를 보다 세밀하게 제어할 수 있습니다. 결과적으로 사용하기가 더 복잡하지만 더 고급 옵션도 제공합니다.
NavigationRegion에 비해 NavigationServer의 다른 장점은 다음과 같습니다.
서버는 굽지 않고 소스 형상을 구문 분석할 수 있습니다. 나중에 사용하기 위해 캐시합니다.
서버에서는 소스 형상 분석을 수동으로 시작할 루트 노드를 선택할 수 있습니다.
서버는 절차적으로 생성된 소스 형상 데이터를 수락하고 베이킹할 수 있습니다.
서버는 동일한 소스 지오메트리 데이터를 (재)사용하면서 여러 탐색 메시를 순차적으로 베이킹할 수 있습니다.
NavigationServer로 탐색 메시를 굽기 위해서는 소스 지오메트리가 필요합니다. 소스 형상은 탐색 메시 베이킹 프로세스에서 고려해야 하는 형상 데이터입니다. 2D 및 3D용 내비게이션 메시는 모두 소스 형상에서 베이킹하여 생성됩니다.
소스 형상 리소스의 2D 및 3D 버전은 각각 NavigationMeshSourceGeometryData2D 및 :ref:`NavigationMeshSourceGeometryData3D<class_NavigationMeshSourceGeometryData3D>`로 제공됩니다.
소스 형상은 시각적 메시, 물리 충돌 또는 윤곽선(2D) 및 삼각형 면(3D)과 같이 절차적으로 생성된 데이터 배열에서 구문 분석된 형상일 수 있습니다. 편의를 위해 소스 형상은 일반적으로 SceneTree의 노드 설정에서 직접 구문 분석됩니다. 런타임 내비게이션 메시 (재)베이크의 경우 지오메트리 구문 분석은 항상 메인 스레드에서 발생한다는 점에 유의하세요.
참고
SceneTree는 스레드로부터 안전하지 않습니다. SceneTree의 소스 지오메트리 구문 분석은 메인 스레드에서만 수행할 수 있습니다.
경고
시각적 메시 및 다각형의 데이터를 GPU에서 수신해야 하므로 프로세스에서 RenderingServer가 중단됩니다. 런타임 (재)베이킹의 경우 물리 모양을 구문 분석된 소스 형상으로 사용하는 것이 좋습니다.
소스 형상은 리소스 내부에 저장되므로 생성된 형상을 여러 베이크에 재사용할 수 있습니다. 예: 동일한 소스 지오메트리에서 다양한 에이전트 크기에 대해 여러 탐색 메시를 베이킹합니다. 또한 나중에 로드할 수 있도록 소스 지오메트리를 디스크에 저장할 수도 있습니다. 런타임에 다시 구문 분석하는 오버헤드를 방지합니다.
일반적으로 기하학 데이터는 매우 단순하게 유지되어야 합니다. 필요한 만큼의 모서리가 필요하지만 가능한 한 적습니다. 특히 2D 중복 및 중첩 형상에서는 폴리곤이 뒤집힐 수 있는 폴리곤 구멍 계산을 강제하므로 피해야 합니다. 중첩된 형상의 예로는 완전히 다른 StaticBody2D 모양의 경계 내부에 배치된 더 작은 StaticBody2D 모양이 있습니다.
다른 스크립팅 언어와 소통하기
런타임에 개별 탐색 메시 청크를 빌드하고 업데이트합니다.
더 보기
이 문서 외에 여러가지 Godot 데모 프로젝트들도 살펴보면 좋습니다.
서로 다른 영역 청크 사이의 잘못 정렬된 가장자리를 방지하기 위해 탐색 메시에는 탐색 메시 베이킹 프로세스에 대한 두 가지 중요한 속성이 있습니다. 베이킹 경계와 테두리 크기입니다. 이를 함께 사용하여 영역 청크 사이의 가장자리를 완벽하게 정렬할 수 있습니다.
베이크 바운드로 베이크되거나 추가 테두리 크기로 베이크된 내비게이션 메시 청크입니다.
2D의 경우 축 정렬 Rect2, 3D의 경우 :ref:`AABB<class_AABB>`인 베이킹 경계는 경계 외부에 있는 모든 형상을 삭제하여 사용되는 소스 형상을 제한합니다.
NavigationPolygon 속성 baking_rect 및 ``baking_rect_offset``를 사용하여 2D 베이킹 바운드를 생성하고 배치할 수 있습니다.
NavigationMesh 속성 filter_baking_aabb 및 ``filter_baking_aabb_offset``를 사용하여 3D 베이킹 바운드를 생성하고 배치할 수 있습니다.
베이킹 범위만 설정하면 또 다른 문제가 여전히 존재합니다. 결과 내비게이션 메시는 가장자리가 제대로 정렬되지 않게 만드는 ``agent_radius``와 같은 필수 오프셋의 영향을 필연적으로 받게 됩니다.
구운 에이전트 반경 오프셋으로 인해 눈에 띄는 간격이 있는 탐색 메시 청크입니다.
탐색 메시의 border_size 속성이 들어오는 곳입니다. 테두리 크기는 베이킹 경계에서 안쪽 여백입니다. 테두리 크기의 중요한 특징은 ``agent_radius``와 같은 대부분의 오프셋 및 후처리에 영향을 받지 않는다는 것입니다.
소스 형상을 삭제하는 대신 테두리 크기는 구운 내비게이션 메시의 최종 표면 일부를 삭제합니다. 베이킹 경계가 충분히 크면 테두리 크기가 문제가 있는 표면 부분을 제거하여 의도한 청크 크기만 남게 됩니다.
가장자리가 정렬되고 간격이 없는 탐색 메시 청크입니다.
참고
베이킹 경계는 모든 인접 청크의 합리적인 양의 소스 형상을 포함할 만큼 충분히 커야 합니다.
경고
3D에서 테두리 크기 기능은 xz축으로 제한됩니다.
내비게이션 메시.
탐색 메시를 생성하거나 베이킹할 때 고려해야 할 몇 가지 일반적인 사용자 문제와 중요한 주의 사항이 있습니다.
- 내비게이션 메시.
탐색 메시 베이킹은 기본적으로 백그라운드 스레드에서 수행되므로 플랫폼이 스레드를 지원하는 한 실제 베이킹은 성능 문제의 원인이 되는 경우가 거의 없습니다(런타임 리베이크를 위한 합리적인 크기와 복잡한 지오메트리 가정).
런타임 시 성능 문제의 일반적인 원인은 노드 및 SceneTree와 관련된 소스 형상에 대한 구문 분석 단계입니다. SceneTree는 스레드로부터 안전하지 않으므로 모든 노드를 기본 스레드에서 구문 분석해야 합니다. 데이터가 많은 일부 노드는 매우 무거워서 런타임 시 구문 분석이 느릴 수 있습니다. TileMap에는 사용된 모든 단일 셀과 구문 분석할 TileMapLayer에 대해 하나 이상의 다각형이 있습니다. 메시를 보유하는 노드는 프로세스에서 렌더링을 지연시키는 RenderingServer에서 데이터를 요청해야 합니다.
성능을 향상하려면 보다 최적화된 모양을 사용하세요. 상세한 시각적 메시 위에 충돌 모양을 적용하고 최대한 많은 지오메트리를 병합하고 단순화합니다. 아무 것도 도움이 되지 않으면 SceneTree를 구문 분석하지 말고 스크립트를 사용하여 소스 형상 절차를 추가하세요. 순수 데이터 배열만 소스 형상으로 사용되는 경우 전체 베이킹 프로세스가 백그라운드 스레드에서 수행될 수 있습니다.
- 내비게이션 메시는 2D에 의도하지 않은 구멍을 만듭니다.
2D 내비게이션 메시 베이킹은 윤곽선 경로를 기반으로 다각형 클리핑 작업을 수행하여 수행됩니다. "구멍"이 있는 다각형은 더 복잡한 2D 다각형을 만드는 데 필요악이지만 복잡한 모양이 많이 포함된 사용자에게는 예측하기 어려울 수 있습니다.
다각형 구멍 계산 시 예상치 못한 문제를 방지하려면 동일한 유형(횡단 가능/방해물)의 다른 윤곽선 내에 윤곽선을 중첩하지 마십시오. 여기에는 노드의 구문 분석된 모양이 포함됩니다. 예: 더 큰 StaticBody2D 모양 안에 더 작은 StaticBody2D 모양을 배치하면 결과 다각형이 뒤집힐 수 있습니다.
- 내비게이션 메시는 3D 형상 내부에 나타납니다.
3D 탐색 메시 베이킹에는 "내부"라는 개념이 없습니다. 형상을 래스터화하는 데 사용되는 복셀 셀은 사용되거나 사용되지 않습니다. 다른 기하학 내부의 바닥에 있는 기하학을 제거하십시오. 이것이 가능하지 않다면 가능한 한 적은 수의 삼각형을 사용하여 내부에 더 작은 "더미" 형상을 추가하여 셀이 무언가로 채워지도록 하십시오.
탐색 메시로 베이킹하도록 설정된 NavigationObstacle3D 모양을 사용하여 형상을 삭제할 수도 있습니다.
NavigationObstacle3D 모양을 사용하여 원치 않는 탐색 메시 부분을 삭제할 수 있습니다.
스크립트 템플릿 만들기
다음 스크립트는 NavigationServer를 사용하여 씬 트리의 소스 지오메트리를 구문 분석하고, 탐색 메시를 굽고, 업데이트된 탐색 메시로 탐색 영역을 업데이트합니다.
extends Node2D
var navigation_mesh: NavigationPolygon
var source_geometry : NavigationMeshSourceGeometryData2D
var callback_parsing : Callable
var callback_baking : Callable
var region_rid: RID
func _ready() -> void:
navigation_mesh = NavigationPolygon.new()
navigation_mesh.agent_radius = 10.0
source_geometry = NavigationMeshSourceGeometryData2D.new()
callback_parsing = on_parsing_done
callback_baking = on_baking_done
region_rid = NavigationServer2D.region_create()
# Enable the region and set it to the default navigation map.
NavigationServer2D.region_set_enabled(region_rid, true)
NavigationServer2D.region_set_map(region_rid, get_world_2d().get_navigation_map())
# Some mega-nodes like TileMap are often not ready on the first frame.
# Also the parsing needs to happen on the main-thread.
# So do a deferred call to avoid common parsing issues.
parse_source_geometry.call_deferred()
func parse_source_geometry() -> void:
source_geometry.clear()
var root_node: Node2D = self
# Parse the obstruction outlines from all child nodes of the root node by default.
NavigationServer2D.parse_source_geometry_data(
navigation_mesh,
source_geometry,
root_node,
callback_parsing
)
func on_parsing_done() -> void:
# If we did not parse a TileMap with navigation mesh cells we may now only
# have obstruction outlines so add at least one traversable outline
# so the obstructions outlines have something to "cut" into.
source_geometry.add_traversable_outline(PackedVector2Array([
Vector2(0.0, 0.0),
Vector2(500.0, 0.0),
Vector2(500.0, 500.0),
Vector2(0.0, 500.0)
]))
# Bake the navigation mesh on a thread with the source geometry data.
NavigationServer2D.bake_from_source_geometry_data_async(
navigation_mesh,
source_geometry,
callback_baking
)
func on_baking_done() -> void:
# Update the region with the updated navigation mesh.
NavigationServer2D.region_set_navigation_polygon(region_rid, navigation_mesh)
using Godot;
public partial class MyNode2D : Node2D
{
private NavigationPolygon _navigationMesh;
private NavigationMeshSourceGeometryData2D _sourceGeometry;
private Callable _callbackParsing;
private Callable _callbackBaking;
private Rid _regionRid;
public override void _Ready()
{
_navigationMesh = new NavigationPolygon();
_navigationMesh.AgentRadius = 10.0f;
_sourceGeometry = new NavigationMeshSourceGeometryData2D();
_callbackParsing = Callable.From(OnParsingDone);
_callbackBaking = Callable.From(OnBakingDone);
_regionRid = NavigationServer2D.RegionCreate();
// Enable the region and set it to the default navigation map.
NavigationServer2D.RegionSetEnabled(_regionRid, true);
NavigationServer2D.RegionSetMap(_regionRid, GetWorld2D().NavigationMap);
// Some mega-nodes like TileMap are often not ready on the first frame.
// Also the parsing needs to happen on the main-thread.
// So do a deferred call to avoid common parsing issues.
CallDeferred(MethodName.ParseSourceGeometry);
}
private void ParseSourceGeometry()
{
_sourceGeometry.Clear();
Node2D rootNode = this;
// Parse the obstruction outlines from all child nodes of the root node by default.
NavigationServer2D.ParseSourceGeometryData(
_navigationMesh,
_sourceGeometry,
rootNode,
_callbackParsing
);
}
private void OnParsingDone()
{
// If we did not parse a TileMap with navigation mesh cells we may now only
// have obstruction outlines so add at least one traversable outline
// so the obstructions outlines have something to "cut" into.
_sourceGeometry.AddTraversableOutline(
[
new Vector2(0.0f, 0.0f),
new Vector2(500.0f, 0.0f),
new Vector2(500.0f, 500.0f),
new Vector2(0.0f, 500.0f),
]);
// Bake the navigation mesh on a thread with the source geometry data.
NavigationServer2D.BakeFromSourceGeometryDataAsync(_navigationMesh, _sourceGeometry, _callbackBaking);
}
private void OnBakingDone()
{
// Update the region with the updated navigation mesh.
NavigationServer2D.RegionSetNavigationPolygon(_regionRid, _navigationMesh);
}
}
extends Node3D
var navigation_mesh: NavigationMesh
var source_geometry : NavigationMeshSourceGeometryData3D
var callback_parsing : Callable
var callback_baking : Callable
var region_rid: RID
func _ready() -> void:
navigation_mesh = NavigationMesh.new()
navigation_mesh.agent_radius = 0.5
source_geometry = NavigationMeshSourceGeometryData3D.new()
callback_parsing = on_parsing_done
callback_baking = on_baking_done
region_rid = NavigationServer3D.region_create()
# Enable the region and set it to the default navigation map.
NavigationServer3D.region_set_enabled(region_rid, true)
NavigationServer3D.region_set_map(region_rid, get_world_3d().get_navigation_map())
# Some mega-nodes like GridMap are often not ready on the first frame.
# Also the parsing needs to happen on the main-thread.
# So do a deferred call to avoid common parsing issues.
parse_source_geometry.call_deferred()
func parse_source_geometry() -> void:
source_geometry.clear()
var root_node: Node3D = self
# Parse the geometry from all mesh child nodes of the root node by default.
NavigationServer3D.parse_source_geometry_data(
navigation_mesh,
source_geometry,
root_node,
callback_parsing
)
func on_parsing_done() -> void:
# Bake the navigation mesh on a thread with the source geometry data.
NavigationServer3D.bake_from_source_geometry_data_async(
navigation_mesh,
source_geometry,
callback_baking
)
func on_baking_done() -> void:
# Update the region with the updated navigation mesh.
NavigationServer3D.region_set_navigation_mesh(region_rid, navigation_mesh)
using Godot;
public partial class MyNode3D : Node3D
{
private NavigationMesh _navigationMesh;
private NavigationMeshSourceGeometryData3D _sourceGeometry;
private Callable _callbackParsing;
private Callable _callbackBaking;
private Rid _regionRid;
public override void _Ready()
{
_navigationMesh = new NavigationMesh();
_navigationMesh.AgentRadius = 0.5f;
_sourceGeometry = new NavigationMeshSourceGeometryData3D();
_callbackParsing = Callable.From(OnParsingDone);
_callbackBaking = Callable.From(OnBakingDone);
_regionRid = NavigationServer3D.RegionCreate();
// Enable the region and set it to the default navigation map.
NavigationServer3D.RegionSetEnabled(_regionRid, true);
NavigationServer3D.RegionSetMap(_regionRid, GetWorld3D().NavigationMap);
// Some mega-nodes like GridMap are often not ready on the first frame.
// Also the parsing needs to happen on the main-thread.
// So do a deferred call to avoid common parsing issues.
CallDeferred(MethodName.ParseSourceGeometry);
}
private void ParseSourceGeometry ()
{
_sourceGeometry.Clear();
Node3D rootNode = this;
// Parse the geometry from all mesh child nodes of the root node by default.
NavigationServer3D.ParseSourceGeometryData(
_navigationMesh,
_sourceGeometry,
rootNode,
_callbackParsing
);
}
private void OnParsingDone()
{
// Bake the navigation mesh on a thread with the source geometry data.
NavigationServer3D.BakeFromSourceGeometryDataAsync(_navigationMesh, _sourceGeometry, _callbackBaking);
}
private void OnBakingDone()
{
// Update the region with the updated navigation mesh.
NavigationServer3D.RegionSetNavigationMesh(_regionRid, _navigationMesh);
}
}
다음 스크립트는 NavigationServer를 사용하여 절차적으로 생성된 탐색 메시 데이터로 탐색 영역을 업데이트합니다.
extends Node2D
var navigation_mesh: NavigationPolygon
var region_rid: RID
func _ready() -> void:
navigation_mesh = NavigationPolygon.new()
region_rid = NavigationServer2D.region_create()
# Enable the region and set it to the default navigation map.
NavigationServer2D.region_set_enabled(region_rid, true)
NavigationServer2D.region_set_map(region_rid, get_world_2d().get_navigation_map())
# Add vertices for a convex polygon.
navigation_mesh.vertices = PackedVector2Array([
Vector2(0.0, 0.0),
Vector2(100.0, 0.0),
Vector2(100.0, 100.0),
Vector2(0.0, 100.0),
])
# Add indices for the polygon.
navigation_mesh.add_polygon(
PackedInt32Array([0, 1, 2, 3])
)
NavigationServer2D.region_set_navigation_polygon(region_rid, navigation_mesh)
using Godot;
public partial class MyNode2D : Node2D
{
private NavigationPolygon _navigationMesh;
private Rid _regionRid;
public override void _Ready()
{
_navigationMesh = new NavigationPolygon();
_regionRid = NavigationServer2D.RegionCreate();
// Enable the region and set it to the default navigation map.
NavigationServer2D.RegionSetEnabled(_regionRid, true);
NavigationServer2D.RegionSetMap(_regionRid, GetWorld2D().NavigationMap);
// Add vertices for a convex polygon.
_navigationMesh.Vertices =
[
new Vector2(0, 0),
new Vector2(100.0f, 0),
new Vector2(100.0f, 100.0f),
new Vector2(0, 100.0f),
];
// Add indices for the polygon.
_navigationMesh.AddPolygon([0, 1, 2, 3]);
NavigationServer2D.RegionSetNavigationPolygon(_regionRid, _navigationMesh);
}
}
extends Node3D
var navigation_mesh: NavigationMesh
var region_rid: RID
func _ready() -> void:
navigation_mesh = NavigationMesh.new()
region_rid = NavigationServer3D.region_create()
# Enable the region and set it to the default navigation map.
NavigationServer3D.region_set_enabled(region_rid, true)
NavigationServer3D.region_set_map(region_rid, get_world_3d().get_navigation_map())
# Add vertices for a convex polygon.
navigation_mesh.vertices = PackedVector3Array([
Vector3(-1.0, 0.0, 1.0),
Vector3(1.0, 0.0, 1.0),
Vector3(1.0, 0.0, -1.0),
Vector3(-1.0, 0.0, -1.0),
])
# Add indices for the polygon.
navigation_mesh.add_polygon(
PackedInt32Array([0, 1, 2, 3])
)
NavigationServer3D.region_set_navigation_mesh(region_rid, navigation_mesh)
using Godot;
public partial class MyNode3D : Node3D
{
private NavigationMesh _navigationMesh;
private Rid _regionRid;
public override void _Ready()
{
_navigationMesh = new NavigationMesh();
_regionRid = NavigationServer3D.RegionCreate();
// Enable the region and set it to the default navigation map.
NavigationServer3D.RegionSetEnabled(_regionRid, true);
NavigationServer3D.RegionSetMap(_regionRid, GetWorld3D().NavigationMap);
// Add vertices for a convex polygon.
_navigationMesh.Vertices =
[
new Vector3(-1.0f, 0.0f, 1.0f),
new Vector3(1.0f, 0.0f, 1.0f),
new Vector3(1.0f, 0.0f, -1.0f),
new Vector3(-1.0f, 0.0f, -1.0f),
];
// Add indices for the polygon.
_navigationMesh.AddPolygon([0, 1, 2, 3]);
NavigationServer3D.RegionSetNavigationMesh(_regionRid, _navigationMesh);
}
}