Nav Link Proxy SmartLinkReached event caught by wrong Nav Link

Sorry for necro, but I’ve ran into the same problem in 4.27. Like many, I cannot upgrade to UE5, so this is still a problem.
The resolution I’ve seen on github is rewriting the whole ID system, which is kinda hard to cherry pick in.

I’ve did some investigation, and the problem is the following:

  • When you place new navlinks, INavLinkCustomInterface::GetUniqueId gets called, and an ID is assigned to the NavLinkComponent
  • Upon loading a world, in the UNavLinkCustomComponent::PostLoad, INavLinkCustomInterface::UpdateUniqueId is called with the saved NavLinkUserId, which essentially modifies the NextUniqueID to be bigger than this, ensuring that future calls of GetUniqueId actually gives back an unique ID, instead of a reused one
  • Then, on OnPreWorldInitialization delegate, this NextUniqueId is reset (INavLinkCustomInterface::OnPreWorldInitialization), nullifying all the work done up until now, and almost guaranteeing, that the next GetUniqueId gives back a duplicate ID

The solution should be simple: move the UpdateUniqueId from PostLoad to somewhere else. PostLoad gets called when the object is loaded, not when it’s actually used, it does not make sense to modify the current world in that function.

Ideally you would need to calculate the currently assigned IDs after the reset, but before Register, so any future ID checks would not cause duplicates. Registering to OnPreWorldInitialization, and manually fixing it could be a way to do it.

Quick and dirty fix for a singular map - if you have attached debuffer - is to put a breakpoint into the INavLinkCustomInterface::ResetUniqueId function, reload your map in editor, and when the debug break stops, take a note of the current value of NextUniqueId. Then put a breakpoint into the INavLinkCustomInterface::GetUniqueId function, and on the first call, modify the NextUniqueId’s value to the previously written down value. This will ensure that when the engine finds a duplicate, it fixes the problem, instead of making it worse (assigning to a different, duplicate value :D)
After the map is loaded, save your level, and on next load, there should be no duplicate IDs.

You could make some editor function that reassigns the IDs, or some automatical fix script, like I mentioned before, if you encounter this issue a lot.