Refactor of NodeLink2

hi there,
I noticed that NodeLink2 has been recently refactored. As I was using an extended version of it I would appreciate some sort of migration guide.

Especially I am curious about how to detect that the agent is on the off-mesh link? Previously it created nodes in a point graph so I could query them and figure it out.

I previously relied a lot on startNode and endNode fields of NodeLink2. Now they are gone. What should I do?

Since it was previously based on point nodes I was using tags for them to filter out off-mesh links for certain units. I assume that now I should change this approach as well.

thanks!

EDIT: I am using AILerp so I am most curious how to detect off-mesh link for that agent type.

I started to digging a bit, but a lot things remains unclear to me.
Besides that it seems that when I am calling GetNodeLink(node) from within ITraversalProvider’s CanTraverse I am getting UnityException: TryGetComponentFastPath can only be called from the main thread.

It creates nodes now as well. But they are put in a new graph type called a LinkGraph.

The NodeLink2 component has a pathfindingTag field. It will propagate this tag to the nodes it creates. So this filtering should work just fine.

Hmm. That’s a good point. Currently, that method cannot be used from separate threads. I’m going to make a change so that this method no longer uses GetComponent internally. It will be included in the next beta update.

The AILerp component unfortunately does not have any built-in method of detecting off-mesh links at the moment.

1 Like

Thanks for the update, it helps a lot.

I am a bit concerned about this that I found in the LinkGraph:

/// It is also not possible to query for the nearest node in this graph. The <see cref="GetNearest"/> method will always return an empty result.
/// This is by design, as all pathfinding should start on the navmesh, not on an off-mesh link.

Since there is no built-in method of detecting off-mesh links and there is no way to get nodes of that graph using GetNearest - how am I supposed to detect off-mesh links by myself? Previously I could query that graph and therefore detect off-mesh links.

You can detect that a node is a node link by checking if it is of type LinkNode.
And you can use the NodeLink2.GetNodeLink method.

There is one thing (probably obvious) that I am missing here. Since I cannot use the GetNearest - how I should obtain the given node that I want to check?

Hi

Hmm. It’s a reasonable question. Ideally the AILerp script would provide this, but since it cannot at the moment, I’ll add a method to get the closest link.

In the next beta update you can use:

AstarPath.active.offMeshLinks.GetNearest(somePoint, maxDistance)

to get the link.

1 Like

thats awesome! Can’t wait to test it out, as it blocks me from upgrading currently.

But I must admit that it seems a little bit like reinventing the wheel. GetNearest was blocked and now GetNearest for off-mesh links will be introduced. What is the benefit coming from it?

I may change it. I also think it’s not a great solution.

The main reason is that I really don’t want link nodes to be included in the search when looking for the closest node by default, as it is rarely what you want.
But I may do this by excluding link graphs by default in the NNConstraint.

Ok, I managed to recreate my solution for detecting off-mesh links.
I am more than happy that you are investing your time on off-mesh links. I believe that the final solution will be great, but currently, the API isn’t as friendly in some places as it could be (or I am overcomplicating things on my side).

In my case, I would like to be able to obtain a startLinkNode and endLinkNode from the NodeLink2 itself. Currently, I have to call AstarPath.active.offMeshLinks.GetNearest(somePoint, maxDistance) from within NodeLink2 (which is kind of weird since these classes describe basically the same thing, or very similar at least) to get the OffMeshLinkConcrete because it is the only class that has references to the nodes. I need the nodes to check if the given path contains nodes used in the link and to determine whether it will be traversed regular or reversed direction.

Hi

I’m designing it so that movement scripts will provide this information directly. For example, the new FollowerEntity movement script has an offMeshLink property which returns the current link that the agent is traversing (complete with information about which direction it is traversing it in).

I hope to adjust the other movement scripts to do this too, but it’s not trivial to do it while maintaining backwards compatibility.

1 Like