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...
내비게이션
NavigationObstacles 노드의 2D 및 3D 버전은 각각 NavigationObstacle2D 및 :ref:`NavigationObstacle3D<class_NavigationObstacle3D>`로 제공됩니다.
탐색 장애물은 탐색 메시 베이킹과 에이전트 회피 모두에 영향을 미칠 수 있다는 점에서 이중 목적을 갖습니다.
``affect_navigation_mesh``를 활성화하면 장애물이 구워질 때 탐색 메시에 영향을 미칩니다.
``avoidance_enabled``를 사용하면 장애물이 회피 에이전트에 영향을 미칩니다.
팁
회피는 기본적으로 활성화되어 있습니다. 회피를 위해 장애물을 사용하지 않는 경우 ``enabled_avoidance``를 비활성화하여 성능을 절약하십시오.
장애물과 내비게이션 메시
탐색 메시 베이킹에 영향을 미치는 탐색 장애물입니다.
내비게이션 메시 베이킹의 경우 장애물을 사용하여 장애물 모양 내부의 다른 모든 소스 형상의 일부를 삭제할 수 있습니다.
이는 내비게이션 메시가 원치 않는 위치에서 구워지는 것을 막는 데 사용할 수 있습니다. 두꺼운 벽과 같은 "단단한" 형상 내부 또는 지붕과 같이 게임플레이에 포함해서는 안 되는 기타 형상 위에.
내비게이션 장애물은 원치 않는 내비게이션 메시를 삭제합니다.
장애물은 베이킹 프로세스에서 형상을 추가하지 않고 형상만 제거합니다. 장애물 모양 내에 있는 래스터화된 소스 형상을 사용하여 모든 (복셀) 셀을 무효화함으로써 이를 수행합니다. 따라서 그 효과와 모양 세부 사항은 베이킹 프로세스에서 사용되는 셀 해상도로 제한됩니다.
내비게이션 메시 굽기에 대한 자세한 사항은 내비게이션 메시.를 참조하세요.
affect_navigation_mesh 속성은 장애물이 탐색 메시 베이킹에 기여하도록 만듭니다. 탐색 메시 베이킹 프로세스에서 다른 모든 노드 개체와 마찬가지로 구문 분석되거나 구문 분석 해제됩니다.
carve_navigation_mesh 속성은 베이킹 오프셋의 영향을 받지 않는 모양을 만듭니다. 탐색 메시 ``agent_radius``에 의해 추가된 오프셋입니다. 기본적으로 스텐실 역할을 하며 이미 오프셋된 탐색 메시 표면을 잘라냅니다. 가장자리 단순화와 같은 베이킹 프로세스의 추가 후처리에 의해 여전히 영향을 받습니다.
장애물 모양과 배치는 height 및 vertices 속성과 장애물의 ``global_position``로 정의됩니다. 정점에 사용된 Vector3의 y축 값은 장애물이 평평한 수평면에 투영되므로 무시됩니다.
스크립트에서 내비게이션 메시를 베이킹할 때 장애물을 투영된 장애물로 절차상 추가할 수 있습니다. 장애물은 소스 형상 분석에 포함되지 않으므로 굽기 직전에 장애물을 추가하는 것으로 충분합니다.
var obstacle_outline = PackedVector2Array([
Vector2(-50, -50),
Vector2(50, -50),
Vector2(50, 50),
Vector2(-50, 50)
])
var navigation_mesh = NavigationPolygon.new()
var source_geometry = NavigationMeshSourceGeometryData2D.new()
NavigationServer2D.parse_source_geometry_data(navigation_mesh, source_geometry, $MyTestRootNode)
var obstacle_carve: bool = true
source_geometry.add_projected_obstruction(obstacle_outline, obstacle_carve)
NavigationServer2D.bake_from_source_geometry_data(navigation_mesh, source_geometry)
Vector2[] obstacleOutline
[
new Vector2(-50, -50),
new Vector2(50, -50),
new Vector2(50, 50),
new Vector2(-50, 50),
];
var navigationMesh = new NavigationPolygon();
var sourceGeometry = new NavigationMeshSourceGeometryData2D();
NavigationServer2D.ParseSourceGeometryData(navigationMesh, sourceGeometry, GetNode<Node2D>("MyTestRootNode"));
bool obstacleCarve = true;
sourceGeometry.AddProjectedObstruction(obstacleOutline, obstacleCarve);
NavigationServer2D.BakeFromSourceGeometryData(navigationMesh, sourceGeometry);
var obstacle_outline = PackedVector3Array([
Vector3(-5, 0, -5),
Vector3(5, 0, -5),
Vector3(5, 0, 5),
Vector3(-5, 0, 5)
])
var navigation_mesh = NavigationMesh.new()
var source_geometry = NavigationMeshSourceGeometryData3D.new()
NavigationServer3D.parse_source_geometry_data(navigation_mesh, source_geometry, $MyTestRootNode)
var obstacle_elevation: float = $MyTestObstacleNode.global_position.y
var obstacle_height: float = 50.0
var obstacle_carve: bool = true
source_geometry.add_projected_obstruction(obstacle_outline, obstacle_elevation, obstacle_height, obstacle_carve)
NavigationServer3D.bake_from_source_geometry_data(navigation_mesh, source_geometry)
Vector3[] obstacleOutline =
[
new Vector3(-5, 0, -5),
new Vector3(5, 0, -5),
new Vector3(5, 0, 5),
new Vector3(-5, 0, 5),
];
var navigationMesh = new NavigationMesh();
var sourceGeometry = new NavigationMeshSourceGeometryData3D();
NavigationServer3D.ParseSourceGeometryData(navigationMesh, sourceGeometry, GetNode<Node3D>("MyTestRootNode"));
float obstacleElevation = GetNode<Node3D>("MyTestObstacleNode").GlobalPosition.Y;
float obstacleHeight = 50.0f;
bool obstacleCarve = true;
sourceGeometry.AddProjectedObstruction(obstacleOutline, obstacleElevation, obstacleHeight, obstacleCarve);
NavigationServer3D.BakeFromSourceGeometryData(navigationMesh, sourceGeometry);
장애물 및 에이전트 회피
회피를 위해 탐색 장애물은 회피 제어 에이전트에 영향을 미치는 정적 또는 동적 장애물로 사용될 수 있습니다.
정적으로 사용될 때 NavigationObstacles는 다각형 정의 영역 외부 또는 내부에서 회피 제어 에이전트를 제한합니다.
동적으로 사용할 경우 NavigationObstacle은 회피 제어 에이전트를 주변 반경으로 밀어냅니다.
정적 물체(static bodies).
vertices 속성이 다각형을 형성하기 위해 위치의 윤곽선 배열로 채워지면 회피 장애물은 정적이라고 간주됩니다.
탐색 에이전트를 차단하거나 포함하기 위해 편집기에 그려진 정적 장애물입니다.
정적 장애물은 에이전트를 사용하여 회피할 때 넘지 말아야 할 경계 역할을 합니다. 물리 충돌과 유사하지만 회피를 위한 것입니다.
정적 장애물은 외곽선
vertices``(위치) 배열로 경계를 정의하며, 3D의 경우 추가 ``height속성을 사용하여 정의합니다.정적 장애물은 2D 회피 모드를 사용하는 에이전트에만 작동합니다.
정적 장애물은 에이전트가 밀려나거나 빨려들어가는 경우 정점의 굴곡 순서를 통해 정의됩니다.
정적 장애물은 위치를 변경할 수 없습니다. 새로운 위치로 워프하고 처음부터 다시 만들 수만 있습니다. 결과적으로 정적 장애물은 프레임마다 위치가 변경되는 용도에 적합하지 않습니다. 지속적인 재구축에는 성능 비용이 높기 때문입니다.
다른 위치로 뒤틀려 있는 정적 장애물은 에이전트가 예측할 수 없습니다. 이로 인해 에이전트 위에 정적 장애물이 뒤틀려 있으면 에이전트가 갇힐 위험이 있습니다.
3D에서 2D 회피가 사용되는 경우 Vector3 정점의 y축은 무시됩니다. 대신 장애물의 전역 y축 위치가 고도 수준으로 사용됩니다. 에이전트는 아래 또는 위에 있는 3D의 정적 장애물을 무시합니다. 이는 장애물과 에이전트의 전역 y축 위치, 고도 수준 및 해당 높이 속성에 따라 자동으로 결정됩니다.
동적 성질
radius 속성이 0보다 큰 경우 회피 장애물은 동적이라고 간주됩니다.
동적 장애물은 에이전트를 사용하여 회피하기 위해 나에게서 멀리 떨어져 주세요. 다른 요원을 피하는 방법과 유사합니다.
동적 장애물은 2D 원의 경우 단일 ``radius``로 경계를 정의하고, 3D 회피의 경우 구 모양을 정의합니다.
동적 장애물은 추가 성능 비용 없이 프레임마다 위치를 변경할 수 있습니다.
에이전트는 설정된 속도를 갖는 동적 장애물의 움직임을 예측할 수 있습니다.
동적 장애물은 혼잡하거나 좁은 공간에서 에이전트를 제한하는 안정적인 방법이 아닙니다.
동일한 장애물에 대해 정적 속성과 동적 속성이 동시에 활성화될 수 있지만 이는 성능 측면에서는 권장되지 않습니다. 이상적으로는 장애물이 움직일 때 정적 정점이 제거되고 대신 반경이 활성화됩니다. 장애물이 새로운 최종 위치에 도달하면 반경이 점차 확대되어 다른 모든 에이전트를 밀어내야 합니다. 장애물 주위에 충분한 안전 공간이 생성되면 정적 정점을 다시 추가하고 반경을 제거해야 합니다. 이렇게 하면 재구성된 정적 경계가 완료될 때 갑자기 나타나는 정적 장애물에 에이전트가 갇히는 것을 방지하는 데 도움이 됩니다.
에이전트와 유사하게 장애물은 avoidance_layers 비트마스크를 사용할 수 있습니다. 자신의 회피 마스크에 일치하는 비트가 있는 모든 에이전트는 장애물을 피합니다.
절차적 하늘.
NavigationServer를 직접 사용하여 노드 없이 스크립트에 새로운 장애물을 생성할 수 있습니다.
스크립트로 생성된 장애물에는 최소한 map 및 position``가 필요합니다. 동적 사용을 위해서는 ``radius``가 필요합니다. 정적 사용을 위해서는 ``vertices 배열이 필요합니다.
# create a new "obstacle" and place it on the default navigation map.
var new_obstacle_rid: RID = NavigationServer2D.obstacle_create()
var default_map_rid: RID = get_world_2d().get_navigation_map()
NavigationServer2D.obstacle_set_map(new_obstacle_rid, default_map_rid)
NavigationServer2D.obstacle_set_position(new_obstacle_rid, global_position)
# Use obstacle dynamic by increasing radius above zero.
NavigationServer2D.obstacle_set_radius(new_obstacle_rid, 5.0)
# Use obstacle static by adding a square that pushes agents out.
var outline = PackedVector2Array([Vector2(-100, -100), Vector2(100, -100), Vector2(100, 100), Vector2(-100, 100)])
NavigationServer2D.obstacle_set_vertices(new_obstacle_rid, outline)
# Enable the obstacle.
NavigationServer2D.obstacle_set_avoidance_enabled(new_obstacle_rid, true)
// Create a new "obstacle" and place it on the default navigation map.
Rid newObstacleRid = NavigationServer2D.ObstacleCreate();
Rid defaultMapRid = GetWorld2D().NavigationMap;
NavigationServer2D.ObstacleSetMap(newObstacleRid, defaultMapRid);
NavigationServer2D.ObstacleSetPosition(newObstacleRid, GlobalPosition);
// Use obstacle dynamic by increasing radius above zero.
NavigationServer2D.ObstacleSetRadius(newObstacleRid, 5.0f);
// Use obstacle static by adding a square that pushes agents out.
Vector2[] outline =
[
new Vector2(-100, -100),
new Vector2(100, -100),
new Vector2(100, 100),
new Vector2(-100, 100),
];
NavigationServer2D.ObstacleSetVertices(newObstacleRid, outline);
// Enable the obstacle.
NavigationServer2D.ObstacleSetAvoidanceEnabled(newObstacleRid, true);
# Create a new "obstacle" and place it on the default navigation map.
var new_obstacle_rid: RID = NavigationServer3D.obstacle_create()
var default_map_rid: RID = get_world_3d().get_navigation_map()
NavigationServer3D.obstacle_set_map(new_obstacle_rid, default_map_rid)
NavigationServer3D.obstacle_set_position(new_obstacle_rid, global_position)
# Use obstacle dynamic by increasing radius above zero.
NavigationServer3D.obstacle_set_radius(new_obstacle_rid, 0.5)
# Use obstacle static by adding a square that pushes agents out.
var outline = PackedVector3Array([Vector3(-5, 0, -5), Vector3(5, 0, -5), Vector3(5, 0, 5), Vector3(-5, 0, 5)])
NavigationServer3D.obstacle_set_vertices(new_obstacle_rid, outline)
# Set the obstacle height on the y-axis.
NavigationServer3D.obstacle_set_height(new_obstacle_rid, 1.0)
# Enable the obstacle.
NavigationServer3D.obstacle_set_avoidance_enabled(new_obstacle_rid, true)
// Create a new "obstacle" and place it on the default navigation map.
Rid newObstacleRid = NavigationServer3D.ObstacleCreate();
Rid defaultMapRid = GetWorld3D().NavigationMap;
NavigationServer3D.ObstacleSetMap(newObstacleRid, defaultMapRid);
NavigationServer3D.ObstacleSetPosition(newObstacleRid, GlobalPosition);
// Use obstacle dynamic by increasing radius above zero.
NavigationServer3D.ObstacleSetRadius(newObstacleRid, 5.0f);
// Use obstacle static by adding a square that pushes agents out.
Vector3[] outline =
[
new Vector3(-5, 0, -5),
new Vector3(5, 0, -5),
new Vector3(5, 0, 5),
new Vector3(-5, 0, 5),
];
NavigationServer3D.ObstacleSetVertices(newObstacleRid, outline);
// Set the obstacle height on the y-axis.
NavigationServer3D.ObstacleSetHeight(newObstacleRid, 1.0f);
// Enable the obstacle.
NavigationServer3D.ObstacleSetAvoidanceEnabled(newObstacleRid, true);