When using NavLinkProxy actors and the Event Received Smart Link Reached, I’ve run into an issue where the wrong NavLinkProxy actor in the world will catch the event. The actor that catches the event is not near the pawn and in fact doesn’t have to be on a nav mesh at all.
It is driving me crazy. I’ve created several different NavLinkProxy classes (in c++ and also in bp) and from them I call specific methods on may AI character to trigger different behaviour.
After 3 days of trying around and debugging I decided to give the reference of the NavLinkProxy to my character and found out, that these are completely wrong.
It is like the character chooses NavLinkProxies which are even not nearby and are even from a completely other subclass of NavLinkProxies.
I have several different NavLinkProxies for different vaulting scenarios in my game.
In this case I positioned the following NavLinkProxy actors in the level
It simply calls a method on my character and it also gives a reference of the current NavLinkProxy to this character. After some testing I saw that this reference is the wrong one!
and even there the NavLinkProxy has sometimes the completely wrong reference.
In my last run the first NavLinkProxy should have been of class VaultOverObstacle_050_NavLink but it was the reference of the last left NavLinkProxy from the first screenshot VaultOverObstacle_200_NavLink3.
This is really a major issue because in this way the NavLinkProxy system is not usable for me.
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));
}
this issue has been causing me grief for some time, fortunately I may have found a practical workaround for this - as the issue is essentially due to the ID of the navlinks being incorrect or duplicated you can try the following to give them all new IDs (I assume):
finish your placement/arrangement of your various navlinks
save the level and close the editor
re-open the editor and load the level
use the World Outliner search to filter down to all your NavLinkProxy actors placed in the level
select them all at once
delete them all at once
undo your delete
as far as I can tell this effectively ‘refreshes’ the IDs of your navlinks and seems to solve the problem
not certain if this works 100% but seems to solve it in my case, will update if I find out any more on this
If you build from source, this should fix the issue as we have moved from an incremental int to using a 64-bit city hash for the ID. If you are waiting for a Epic Games Launcher build, it will be included in 5.3.
The fix was included as part of 5.3. I do not know what issue may be showing as open still on GitHub, but the NavLink IDs have been changed over to the 64-bit hash.
Hey,
I’ve stumbled on exactly this error in UnrealEngine 4.27.2 in my project.
I tried to override the RegisterCustomLink() in C++ creating a child class:
UMyNavigationSystemV1 : public UNavigationSystemV1
Not sure how to then tell the engine to use this new navigation system.
Changes in DefaultEngine.ini, like this:
[/Script/Engine.Engine]
NavigationSystemClassName=/Script/MyProject.MyNavigationSystemV1
have no effect.
I’ve eventually upgraded the project to Unreal 5.4.2.
The error with CustomLink ids seems to be solved.
I removed my subclass for NavigationSystem - no need to play with that anymore.
Cheers,
Bartosz
Now I need to understand why AIs seem to jump sideways sometimes :), but that’s diffrent thing