RichAI clamping inside mesh and prematurely

So I’m having issues with my RichAI clamping inside objects and not using available mesh links. It correctly pathfinds to the mesh links. However, before it actually traverses the mesh links, it clamps to the neighboring recast mesh.

I saw this comment in the code for the RichAI.ClampToNavmesh() function:

// Return the new position, but ignore any changes in the y coordinate from the ClampToNavmesh method as the y coordinates in the navmesh are rarely very accurate

Okay, that makes sense. I can get that. This line explains why the clamping is inside the object and not on top of it. And there are opposite instances where the RichAI clamps off a ledge and falls down to the recast graph below. Gotcha.

However, this code should not be reached in my use case. There is an available mesh link to use, and I have a subscriber to it which starts a jump instead of the default lerp. It is simply clamping before it has a chance to traverse the link.

Here are my settings.
I’ve experimented using .35 radius bake - .35 radius character, .5 radius bake - .35 radius character, and .5 radius bake - .5 radius character. For every combination, the error still persists, but it just exists in different places. With .5 bake .35 character, it seems to snap inside objects more. With .35 bake .35 character, it seems to snap off ledges more but still snaps inside objects. So none of these solve the issue. They simply offset it in one way or another.

Any ideas?

Bump! Anyone else run into this before?

Hi

Are you sure the coroutine assigned to RichAI.onTraverseOffMeshLink (which I assume you are using) runs for the whole duration of the jump? The RichAI will not clamp to the navmesh as long as that coroutine is running.

@aron_granberg Thanks for the reply! Sorry, I missed this. Okay so I recorded a quick video to show what’s going on. Whenever “Clamp” shows in the console, the RichAI ClampToNavmesh() ran successfully and performed a Clamp. “Jump” is when the Coroutine starts, and “Jump Over” is when the Coroutine ends.

As you can see by the output, the problem occurs without the Coroutine even having a chance to start. It clamps prematurely… somehow.

I’ll start frequently checking the forum again :sweat_smile:

Hmm, that is odd. I mean something is making it move inside the wall.
May I see your coroutine code?

Sure! However, I don’t think this is the root of the issue.

  1. Here’s a follow-up gif where the issue is still happening with default traversal behavior.
  2. I made a new RichAI that’s totally separated from my entity character system, and it’s still having the issue. So the issue is not with my character code interfering with the agent.

Default traversal behavior, using my character system

Vanilla RichAI with RB having issues

    private IEnumerator TraverseOffMeshLink(RichSpecial link)
    {
        traversingLink = true;     

        Debug.Log("Jump");

        // If the gap to cross is small
        if (Vector3.Distance(link.second.position.Flat(),transform.position.Flat()) > 1.5f)
            // Create a maximum possible velocity so that it can cross the gap (running jump)
            entity.p.TransferAgentVelocityToRB(link.second.position - transform.position);

        // If the target height is lower than our start height and horizontally it's close
        if (link.second.position.y < transform.position.y && Vector3.Distance(link.second.position.Flat(),transform.position.Flat()) < 1.5f)
            StartJump(false); 
        else
            StartJump(); 

        do
        {
            movementDirection = (link.second.position - transform.position).Flat().ClampMagnitude(1f,.4f);
            yield return new WaitForSeconds(.2f);
        }
        while (entity.p.PhysicsState == GroundState.InAir);

        movementDirection = Vector3.zero;
        traversingLink = false;

        Debug.Log("Jump Over");
    }

Ooookay. I’m back with more useful information. I decided to upgrade to v4.3.35. And whadda ya know, it’s fixed! And I figured out why too, which leads into another question :sweat_smile:

Previously, I had extended the NodeLink2 code to add support for tags, so that only certain seekers could use certain links. So without reverting to 4.2 and using the modified NodeLink2 code, I can’t confirm exactly, but It’s likely that was the issue. This was the previous post about tag support for links.

Anyways! So this clamping issue seems to be resolved, however, I’m returning to my issue of tagging PointNodes. This might be suited for another forum post…

How exactly does tagging point nodes work? I’m using a Recast Graph and Point graph combo. Point graph being required by NodeLink2, and Recast Graph for usual traversal.

       // This runs OnPostScan()
       foreach (NodeLink2 nodeLink in nodeLinks)
       {
           nodeLink.OnPostScan();
           
           // Tag link
           if (nodeLink.startNode != null) nodeLink.startNode.Tag = (uint)Tag;
           if (nodeLink.endNode != null) nodeLink.endNode.Tag = (uint)Tag;
       }

I’m using that code, but no matter what I throw at it… I can’t seem to get my characters to ignore PointNodes. GraphUpdateScene.cs works well for sectioning off portions of my RecastGraph, however, it won’t touch the PointGraph (or if it is, my seekers don’t care).

In my Seeker component, I’ve disabled traversal on every tag except Ground. Then, I’m trying to assign all my PointNode tags to a randomly high layer like 20 for example. No dice, they don’t care and use all PointNodes in the graph.

Sorry to shift topics :sweat_smile: I can move to another post