Navigation system how-to's


There’s a lot of functionality in UE4 for navigation other than path_to_actor. How do I interface to it, or if you can’t, how do I create my own interfaces to it from C++?

For example, Path To Location, Project Point To Navigation, Test Path Sync, and a few others. Also, checking the actor’s agent info.

While navigating I sometimes turn on or off, or change, the AI’s collision. Any way to do that from Sk?



How do you do these things you describe right now? What exact calls are you looking to replicate in Sk?


Here’s an example. An AI is going to test if there exists a valid path to a target point (EndLoc):

const UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld());
const ANavigationData* NavData = NavSys->GetNavDataForProps(GetNavAgentPropertiesRef());
if (NavData)
	TSubclassOf<UNavigationQueryFilter> FilterClass = UNavigationQueryFilter::StaticClass();
	FSharedConstNavQueryFilter QueryFilter = UNavigationQueryFilter::GetQueryFilter(*NavData, FilterClass);
	FPathFindingQuery MyAIQuery = FPathFindingQuery(this, *NavData, GetPawn()->GetActorLocation(), EndLoc, QueryFilter);
	return NavSys->TestPathSync(MyAIQuery, EPathFindingMode::Regular);

The key function is TestPathSync from the Navigation system. It does a test optimized for speed that returns true or false.

In this next example, I have a point (Goal) that is outside a navigation test, and I want the nearest point inside a navigation mesh to it:

	const FNavAgentProperties& AgentProps = GetNavAgentPropertiesRef();
	FNavLocation NavLoc;
	if (!GetWorld()->GetNavigationSystem()->ProjectPointToNavigation(Goal, NavLoc, AgentProps.GetExtent(), &AgentProps))
		return false;

On both examples, I reference the agent properties. The agent properties are a real piece of … work? But sometimes we need to reference them.

We do a bit of collision traces throughout:

			FHitResult outHit;
			FCollisionQueryParams params;
			params.bTraceComplex = true;
			FCollisionResponseParams responseParam;
			bool hit = GetWorld()->LineTraceSingleByChannel(outHit, StartLoc, EndLoc, ECC_Pawn, params, responseParam);

So for any of these, I can wrap them up in C++ functions, declare them as UFUNCTION(BlueprintCallable), and see them in Sk, right?


Some portions of this code are apparently not exposed to scripting/Blueprints. There might be a different “Blueprint way” to accomplish the same thing.

Yes, you can of course wrap any C++ code you want into a custom UFUNCTION and call it from Sk.


Simple Move To Location , Project Point to Navigation, and Line Trace By Channel all have blueprint nodes that I can place in any actor or level BP. How would I access those?


SimpleMoveToLocation exists in Sk and is called simple_move_to_location. You can look at the coroutine _path_to_actor as an example which uses the similar function simple_move_to_actor to implement navigation in a durational fashion.

ProjectPointToNavigation is available in Sk as project_point_to_navigation. You might be able to get the NavAgentProperties struct directly from your NavMomentComponent via @nav_agent_props.

LineTraceByChannel exists as SystemLib.line_trace_single, you should be able to pass the same parameters as in your C++ sample code.

Let me know if you get it to work!