Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Unable to get NavArea Flags in SetMoveSegment() using custom PathFollowingComponent derived from UCrowdFollowingComponent

Hey guys,

So I've been following the tutorial shown HERE and have run into a wall while trying to get this working with the UCrowdFollowingComponent. (Parent)

Whenever I do a MoveTo(), SetMoveSegment() only contains a SegmentStart with NULL flags so I can't determine whether we are traversing a 'jump' segment or not using the method shown in the tutorial.

Is there another way to determine if the current Segment we are about to traverse is a specific type of NavLinkProxy, or a possible way of making the UCrowdFollowingComponent correctly use the SetMoveSegment() function?

Through testing I have found if IsCrowdSimulationEnabled() is false then SetMoveSegment() works as expected (As a majority of the component is disabled), however if we simply SuspendCrowdSteering() It still fails to work correctly.

I guess I'm looking for point in the right direction/explanation of why this doesn't work.


Product Version: UE 4.15 Preview
more ▼

asked Jan 30 '17 at 05:13 AM in C++ Programming

avatar image

275 14 20 30

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

So after much screwing around I finally figured out I've been mostly chasing my tail getting this to work, as it's rather poorly documented/explained.

So to elaborate on my final solution:

  1. UCrowdFollowingComponent does not use SetMoveSegment() in the same way as UPathFollowingComponent, so you will need to use StartUsingCustomLink() instead. I ended up calling PauseMove(), setting the CharacterMovement to MOVE_Flying, and then manually lerping the characters position to DestPoint in the TickComponent(). Once it finished I set the movement mode back to MOVE_Walking and called ResumeMove()

  2. When placing NavLinkProxy actors in the level make sure the 'PointLinks' array under the 'Simple Link' Category is empty. Make sure you check on 'Smart Link Is Relevant'. Simple links have a higher priority in the Nav System, so if you have both on, StartUsingCustomLink() will never get called. (Which isn't explained anywhere....)

  3. If you want to place NavLinkProxy actors in the level at runtime; after you spawn the actor, you need to call: NavLinkProxy->GetSmartLinkComp()->ForceNavigationRelevancy(true) which will actually get the NavLink to actually appear. If that doesn't work you may also need to call NavSys->AddDirtyArea(NavLinkProxy->GetComponentsBoundingBox(), ENavigationDirtyFlag::All); so the NavMesh around the link rebuilds.

And that should be about it. :)

more ▼

answered Mar 24 '17 at 12:38 PM

avatar image

275 14 20 30

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

So after about a week of screwing around I've come across a solution which is hacky at best.

I found the code in the CrowdManager which was supposed to be detecting smartlinks was never working, as the following line in void UCrowdManager::UpdateAgentPaths() was always returning a NavLinkId of 0:

 const uint32 NavLinkId = PImplNavMesh->GetLinkUserId(AnimInfo.polyRef);

So I ended up finding that the valid NavLinkId was offset by one in the Detour NavMesh connection data so long as we tick the 'Smart Link is relevant' box when placing a NavLink.

I ended up making the following change in DetourNavMesh.cpp so we fetch that NavLinkId instead of the invalid one.

See below:

 const dtOffMeshConnection* dtNavMesh::getOffMeshConnectionByRef(dtPolyRef ref) const
     const unsigned int idx =  ip - tile->header->offMeshBase;
     dtAssert(idx < (unsigned int)tile->header->offMeshConCount);
 #if 1 // UG_CHANGE: Rather hacky way to guarantee that we correctly fetch the correct UserID for the custom link on this NavMesh.
     // As far as I can tell, the Custom Link ID is ALWAYS at the next index if the Smart Link is relevant.
     // So double check it is actually the case, and then return it.
     if (tile->offMeshCons[idx].userId == 0 &&
         idx + 1 < (unsigned int)tile->header->offMeshConCount &&
         tile->offMeshCons[idx + 1].userId != 0)
         return &tile->offMeshCons[idx + 1];
 #endif // UG_CHANGE:
     return &tile->offMeshCons[idx];

I don't have a great grasp of how the Detour NavMesh actually works fully however, so I'm not sure this is ACTUALLY what I should be doing, and if this works in all cases.

This is really only a tentative answer until I can get an answer from someone who actually knows the system. (Not me!)

more ▼

answered Feb 20 '17 at 02:51 AM

avatar image

275 14 20 30

avatar image FacePalm.exe Feb 26 '17 at 11:35 PM

Should mention that this doesn't work with dynamically spawned NavLinks.

Posted a bug about it HERE.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question