Sorry, I should have posted the solution we went with. This is in NavigationSystem.cpp. Look for the following line in the RegisterCustomLink function.
// Fix for link id overwriting an existing link id in the CustomLinksMap
while (CustomLinksMap.Contains(LinkId))
{
LinkId = INavLinkCustomInterface::GetUniqueId();
}
void UNavigationSystemV1::RegisterCustomLink(INavLinkCustomInterface& CustomLink)
{
ensureMsgf(CustomLink.GetLinkOwner() == nullptr || GetWorld() == CustomLink.GetLinkOwner()->GetWorld(),
TEXT("Registering a link from a world different than the navigation system world should not happen."));
uint32 LinkId = CustomLink.GetLinkId();
// if there's already a link with that Id registered, assign new Id and mark dirty area
// this won't fix baked data in static navmesh (in game), but every other case will regenerate affected tiles
if (CustomLinksMap.Contains(LinkId))
{
// Fix for link id overwriting an existing link id in the CustomLinksMap
while (CustomLinksMap.Contains(LinkId))
{
LinkId = INavLinkCustomInterface::GetUniqueId();
}
UE_LOG(LogNavLink, VeryVerbose, TEXT("%s new navlink id %u."), ANSI_TO_TCHAR(__FUNCTION__), LinkId);
CustomLink.UpdateLinkId(LinkId);
UObject* CustomLinkOb = CustomLink.GetLinkOwner();
UActorComponent* OwnerComp = Cast<UActorComponent>(CustomLinkOb);
AActor* OwnerActor = OwnerComp ? OwnerComp->GetOwner() : Cast<AActor>(CustomLinkOb);
if (OwnerActor)
{
ENavLinkDirection::Type DummyDir = ENavLinkDirection::BothWays;
FVector RelativePtA, RelativePtB;
CustomLink.GetLinkData(RelativePtA, RelativePtB, DummyDir);
const FTransform OwnerActorTM = OwnerActor->GetTransform();
const FVector WorldPtA = OwnerActorTM.TransformPosition(RelativePtA);
const FVector WorldPtB = OwnerActorTM.TransformPosition(RelativePtB);
FBox LinkBounds(ForceInitToZero);
LinkBounds += WorldPtA;
LinkBounds += WorldPtB;
AddDirtyArea(LinkBounds, FNavigationOctreeController::OctreeUpdate_Modifiers);
}
}
CustomLinksMap.Add(LinkId, FNavigationSystem::FCustomLinkOwnerInfo(&CustomLink));
}