Препятствия: избегание, запекание и carve
Выбрать механизм и проверить, что изменилось в пути.
Навигационное препятствие имеет две независимые роли: участие в избегании и вклад в запекание. Оно не является физическим коллайдером. Добавление NavigationObstacle2D в уже работающий уровень не вырезает дыру в готовой навигации автоматически.
Выбрать нужный механизм
| Требование | Решение |
|---|---|
| Не проходить физическим телом сквозь стену | Коллайдер и движение тела с коллизией. |
| Получить маршрут вокруг постоянной стены | Учесть стену/препятствие в исходных данных и перезапечь навигацию. |
| Корректировать скорость рядом с движущимся объектом | Избегание агента и препятствие на той же карте с подходящими масками. |
AffectNavigationMesh разрешает включать Entity препятствия в разбор геометрии для запекания. CarveNavigationMesh выбирает способ вырезания при таком запекании. Изменение этих флагов само по себе не запускает разбор и не обновляет уже назначенный ресурс.
AvoidanceEnabled независимо включает участие в избегании. Радиус задаёт круг динамического препятствия, вершины — статический контур. При перемещении статического контура требуется обновление его данных; не считайте его физической стеной или гарантией обхода плотной толпы. Слои избегания и навигационные слои — разные маски.
Проверенный пример запекания препятствия 2D
Сохраните ObstacleBake2D.cs в C#-проекте Reckfell 1.0.0:
using Reckfell;
using System;
public static class ObstacleBake2D
{
public static NavigationPolygon Bake(bool carve)
{
using var source = new NavigationMeshSourceGeometryData2D();
source.AddTraversableOutline(new[]
{
new Vector2(0, 0), new Vector2(20, 0),
new Vector2(20, 10), new Vector2(0, 10)
});
source.AddProjectedObstruction(new[]
{
new Vector2(8, 3), new Vector2(12, 3),
new Vector2(12, 7), new Vector2(8, 7)
}, carve);
var polygon = new NavigationPolygon { AgentRadius = 1, CellSize = 1 };
NavigationServer2D.BakeFromSourceGeometryData(polygon, source);
if (polygon.GetPolygonCount() > 0) return polygon;
polygon.Dispose();
throw new InvalidOperationException("Obstacle bake produced no polygons.");
}
}В примере проходимая область — 20×10, прямоугольное препятствие занимает x=8–12, y=3–7. Вызовите Bake(true) или Bake(false), назначьте возвращённый ресурс региону и дождитесь публикации карты. Сам source-data помощник не требует Entity препятствия в дереве. Возвращённым ресурсом владеет вызывающий код.
При carve = true вырезание применяется после отступа под AgentRadius: сам контур выреза не получает дополнительный зазор радиуса. При false препятствие участвует в обычном отступе, поэтому запретная область увеличивается. Не используйте carve как способ автоматически обеспечить место для физического тела у края выреза.
В выполненной проверке путь из (2, 5) в (18, 5) после явного запекания огибал вырез. Центр препятствия (10, 5) отсутствовал на навигационной поверхности. Вариант без carve с радиусом агента 1 дал больший отступ от центра до ближайшей проходимой точки.
Что не изменяет маршрут
В той же проверке сначала была добавлена Entity NavigationObstacle2D с AffectNavigationMesh = true и включённым избеганием. Запрос MapGetPath по прежнему ресурсу остался прямым. Маршрут изменился только после явного запекания и назначения нового ресурса.
Если нужен движущийся объект, постоянное перезапекание может быть неподходящим решением. Выбирайте избегание для корректировки скорости, а для двери или специального перехода рассмотрите навигационную связь. Ни один вариант не освобождает игру от проверки застревания и недостижимости.
Диагностика
- Препятствие не меняет путь: проверьте, было ли оно разобрано и выполнено ли новое запекание; один флаг не обновляет ресурс.
- Агент не реагирует: проверьте карту,
AvoidanceEnabled, слои/маски и использованиеVelocityComputedв примере агента. - Тело задевает край выреза: проверьте carve, радиус запекания и физическую форму.
- Есть обходной путь, но персонаж идёт прямо: пересчитайте сохранённый маршрут после публикации новой геометрии.
Проверены отсутствие автоматического перезапекания, точный source-data код, обход выреза и различие carve true/false в 2D. Разбор Entity препятствия при запекании сверён с исходниками; статическое избегание, плотная толпа, препятствия 3D и производительность не проверены выполнением.