reckfellENGINE

Навигационные связи: переходы и ограничения

Соединить раздельные участки карты и правильно выполнить переход.

На этой странице

NavigationLink2D и NavigationLink3D добавляют переход между двумя участками навигации: например, лестницу, прыжок или телепорт. Связь участвует в поиске пути, но не выполняет движение. Анимацию, перенос персонажа, ожидание двери и проверку возможности перехода реализует игра.

Подготовить связь 2D

Нужна активная карта с двумя подготовленными навигационными регионами. Сначала убедитесь, что без связи они действительно разъединены: увеличенный допуск соединения рёбер может уже соединять близкие регионы.

  1. Добавьте NavigationLink2D в уровень и назначьте правильную навигационную карту, если она отличается от карты мира.
  2. Поместите стартовый конец рядом с первым регионом, конечный — рядом со вторым. StartPosition и EndPosition у Entity задаются локально относительно самой связи. У NavigationServer эти координаты глобальные.
  3. У карты проверьте радиус MapSetLinkConnectionRadius: он определяет поиск поверхности рядом с каждым концом, а не максимальную длину перехода. Если рядом с одним концом нет подходящего полигона, полного пути не будет.
  4. Для движения в обе стороны включите Bidirectional. При false допускается направление от старта связи к её концу.
  5. Согласуйте навигационные слои регионов, связи и запроса. Например, регионы на слое 1, связь на слое 2 требуют маски запроса 3; одной маски 1 недостаточно.
  6. Дождитесь публикации изменений карты и выполните новый запрос в обоих направлениях. Сравнивайте концы результата с исходными позициями: запрос пути.

В проверочной карте регионы занимают прямоугольники x=0–10 и x=20–30, y=0–10. Связь соединяет глобальные точки (9, 5) и (21, 5). После её добавления маршрут от (1, 5) до (29, 5) становится полным. Отключение связи или перенос конечной точки за радиус подключения снова разрывает маршрут.

Создание через сервер

Для процедурного уровня сохраните NavigationConnection2D.cs в C#-проекте Reckfell 1.0.0:

C#
using Reckfell;
using System;

public sealed class NavigationConnection2D : IDisposable
{
    public Rid Handle { get; private set; }

    public NavigationConnection2D(Rid map, Vector2 start, Vector2 end,
        uint layers = 1, bool bidirectional = true, ulong ownerId = 0)
    {
        if (!map.IsValid) throw new ArgumentException("A live map is required.", nameof(map));
        Handle = NavigationServer2D.LinkCreate();
        NavigationServer2D.LinkSetStartPosition(Handle, start);
        NavigationServer2D.LinkSetEndPosition(Handle, end);
        NavigationServer2D.LinkSetNavigationLayers(Handle, layers);
        NavigationServer2D.LinkSetBidirectional(Handle, bidirectional);
        NavigationServer2D.LinkSetOwnerId(Handle, ownerId);
        NavigationServer2D.LinkSetMap(Handle, map);
        NavigationServer2D.LinkSetEnabled(Handle, true);
    }

    private void EnsureAlive()
    {
        if (!Handle.IsValid) throw new ObjectDisposedException(nameof(NavigationConnection2D));
    }

    public void SetEnabled(bool enabled)
    {
        EnsureAlive();
        NavigationServer2D.LinkSetEnabled(Handle, enabled);
    }

    public void SetBidirectional(bool enabled)
    {
        EnsureAlive();
        NavigationServer2D.LinkSetBidirectional(Handle, enabled);
    }

    public void SetLayers(uint layers)
    {
        EnsureAlive();
        NavigationServer2D.LinkSetNavigationLayers(Handle, layers);
    }

    public void Dispose()
    {
        if (!Handle.IsValid) return;
        NavigationServer2D.FreeRid(Handle);
        Handle = default;
    }
}

Передайте конструктору RID живой карты и глобальные координаты концов. Храните помощник у владельца процедурного перехода; вызовите Dispose() при его удалении, до освобождения карты. Повторный Dispose() безопасен; методы после освобождения отклоняются. Не освобождайте Handle отдельно: им владеет помощник.

Если используете обычную Entity NavigationLink2D, её жизненный цикл уже управляет собственным RID. Не смешивайте два способа владения одной связью. Перемещение Entity преобразует её локальные концы в новые глобальные координаты сервера — это проверено выполнением.

Как выполнить сам переход

В результате запроса включите метаданные. PathTypes различает участки регионов и связей; PathRids указывает RID владельца точки, PathOwnerIds — ID объекта-владельца, если он назначен. В конструктор помощника можно передать GetInstanceId() объекта, который управляет переходом.

Когда персонаж дошёл до начала перехода, передайте управление своей логике: выполните прыжок, дождитесь платформы или перенесите персонажа. Затем возобновите обычное следование пути. Одни точки маршрута не гарантируют наличие пола и не проверяют физическую безопасность траектории. Нулевой ID владельца нельзя считать существующей Entity.

EnterCost и TravelCost влияют на стоимость поиска, а не на скорость персонажа или длительность анимации. У проверенной серверной связи значения по умолчанию — 0 и 1. Выбор между несколькими альтернативными переходами нужно проверять отдельно на своей карте.

Ограничение IncludedRegions в 1.0.0

В установленной сборке непустой IncludedRegions блокирует проверенный путь через NavigationLink даже при включении обоих его регионов. Очистка этого списка восстанавливает маршрут. Это воспроизведённое ограничение, а не неправильная настройка слоёв.

Для такого случая оставьте IncludedRegions пустым и ограничивайте доступ навигационными слоями. Обязательно проверьте, что маски исключают все запрещённые участки. Не добавляйте нужный конечный регион в ExcludedRegions как обход: исключение тоже разрывает путь. Поведение фильтров для связей 3D этим набором не проверено.

Диагностика

  • Прямой путь есть, обратного нет: проверьте Bidirectional и направление концов.
  • Связь видна, но не используется: проверьте карту, маски, подключение обоих концов и IncludedRegions.
  • В редакторе концы выглядят правильно, в коде смещены: различайте локальные координаты Entity и глобальные координаты NavigationServer.
  • Персонаж идёт по воздуху: связь создала маршрут, но игра не реализовала специальное движение.

Проверены серверный помощник, оба направления, слои, отключение, радиус концов, RID/ID в метаданных, освобождение, локальные/глобальные позиции Entity и ограничение фильтра. Анимация движения, избегание, размещение мышью, запекание, связи 3D и выбор по стоимости не проверены.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.