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 версії вузлів NavigationObstacles доступні як NavigationObstacle2D і NavigationObstacle3D відповідно.
Навігаційні перешкоди мають подвійне призначення, оскільки вони можуть впливати як на запікання навігаційної сітки, так і на уникнення агента.
Якщо ввімкнено
affect_navigation_mesh, перешкода впливатиме на навігаційну сітку під час запікання.Якщо
avoidance_enabled, перешкода впливатиме на агентів уникнення.
Порада
Уникнення ввімкнено за умовчанням. Якщо перешкода не використовується для уникнення, вимкніть enabled_avoidance, щоб зберегти продуктивність.
Перешкоди та навігаційна сітка
Навігаційні перешкоди, що впливають на запікання навігаційної сітки.
Для запікання навігаційної сітки можна використовувати перешкоди, щоб відкинути частини всієї іншої вихідної геометрії всередині форми перешкоди.
Це можна використовувати, щоб зупинити запікання навігаційних сіток у небажаних місцях, напр. всередині «суцільної» геометрії, як-от товсті стіни, або поверх іншої геометрії, яку не слід включати в ігровий процес, як-от дахи.
Навігаційні перешкоди відкидають небажану навігаційну сітку.
Перешкода не додає геометрії в процесі випікання, вона лише видаляє геометрію. Це робиться шляхом анулювання всіх (воксельних) комірок із растеризованою вихідною геометрією, які знаходяться в межах форми перешкоди. Таким чином, його ефект і деталі форми обмежені роздільною здатністю комірки, яка використовується в процесі випічки.
Додаткову інформацію про запікання навігаційної сітки див. Використання навігаційних сіток.
Властивість affect_navigation_mesh робить перешкоду учасником запікання навігаційної сітки. Він буде аналізуватися або скасовуватися, як і всі інші об’єкти вузлів у процесі запікання навігаційної сітки.
Властивість carve_navigation_mesh робить форму незалежною від зсувів запікання, напр. зсув, доданий навігаційною сіткою agent_radius. По суті, він діятиме як трафарет і врізатиметься у вже зміщену поверхню навігаційної сітки. На нього все одно впливатиме подальша постобробка процесу випікання, наприклад спрощення країв.
Форма та розташування перешкоди визначаються властивостями height і vertices, а також global_position перешкоди. Значення осі Y для будь-якого Vector3, що використовується для вершин, ігнорується, оскільки перешкода проектується на плоску горизонтальну площину.
Під час запікання навігаційних сіток у сценаріях перешкоди можна додавати процедурно як спроектовану перешкоду. Перешкоди не беруть участь у аналізі вихідної геометрії, тому достатньо додати їх безпосередньо перед запіканням.
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);
Перешкоди та уникнення агента
Для уникнення навігаційні перешкоди можуть використовуватися як статичні або динамічні перешкоди для впливу на керованих агентів уникнення.
При статичному використанні навігаційні перешкоди обмежують уникнення контрольованих агентів за межами або всередині визначеної полігоном області.
При динамічному використанні Навігаційні перешкоди відштовхують агентів, керованих уникненням, у радіусі навколо них.
Уникнення статичних перешкод
Перешкода для уникнення вважається статичною, якщо її властивість vertices заповнюється структурним масивом позицій для формування багатокутника.
Статична перешкода, намальована в редакторі для блокування або утримання агентів навігації.
Статичні перешкоди діють як жорсткі межі, які заборонено перетинати, щоб уникнути їх за допомогою агентів, напр. схоже на фізичне зіткнення, але для уникнення.
Статичні перешкоди визначають свої межі за допомогою масиву контурних
вертик(положень), а у випадку 3D за допомогою додаткової властивостіheight.Статичні перешкоди працюють лише для агентів, які використовують режим уникнення 2D.
Статичні перешкоди визначають порядок звивистих вершин, якщо агенти виштовхуються або засмоктуються.
Статичні перешкоди не можуть змінити своє положення. Їх можна лише деформувати на нову позицію та відновити з нуля. У результаті статичні перешкоди погано підходять для використання, де положення змінюється кожного кадру, оскільки постійне відновлення має високу вартість продуктивності.
Агенти не можуть передбачити статичні перешкоди, які переміщуються в інше положення. Це створює ризик застрягання агентів, якщо статична перешкода буде деформована поверх агентів.
Коли уникання 2D використовується в 3D, вісь y вершин Vector3 ігнорується. Натомість глобальне положення перешкоди по осі Y використовується як рівень висоти. Агенти ігноруватимуть статичні перешкоди в 3D, які знаходяться під або над ними. Це автоматично визначається глобальним положенням осі ординат як перешкоди, так і агента як рівень висоти, а також їхні відповідні властивості висоти.
Динамічне уникнення перешкод
Перешкода для уникнення вважається динамічною, якщо її властивість радіус більше нуля.
Динамічні перешкоди діють як м’який об’єкт, будь ласка, відійдіть від мене, щоб уникнути за допомогою агентів, напр. подібно до того, як вони уникають інших агентів.
Динамічні перешкоди визначають свої межі єдиним
радіусомдля двовимірного кола або, у разі уникнення 3D, форму сфери.Динамічні перешкоди можуть змінювати своє положення кожного кадру без додаткових витрат на продуктивність.
Динамічні перешкоди із заданою швидкістю можуть бути передбачені в їх русі агентами.
Динамічні перешкоди не є надійним способом стримування агентів у людних або вузьких місцях.
Хоча як статичні, так і динамічні властивості можуть бути активними одночасно на одній перешкоді, це не рекомендується для продуктивності. В ідеалі, коли перешкода рухається, статичні вершини видаляються, а замість цього активується радіус. Коли перешкода досягне нового кінцевого положення, вона повинна поступово збільшувати свій радіус, щоб відштовхнути всіх інших агентів. Якщо навколо перешкоди створено достатньо безпечного простору, слід знову додати статичні вершини та видалити радіус. Це допомагає уникнути того, щоб агенти застрягли на статичній перешкоді, що раптово з’явилася, коли відновлена статична межа буде завершена.
Подібно до агентів, перешкоди можуть використовувати бітову маску avoidance_layers. Усі агенти з відповідним бітом на власній масці уникнення уникатимуть перешкоди.
Процесуальні перешкоди
Нові перешкоди можна створювати в сценарії без Node, використовуючи безпосередньо NavigationServer.
Перешкоди, створені за допомогою сценаріїв, потребують принаймні карти і позиції. Для динамічного використання потрібен радіус. Для статичного використання необхідний масив вершин.
# 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);