Navigation system how-to's


#1

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?

Thanks!


#2

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


#3

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.AddIgnoredActor(GetPawn());
			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?


#4

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.


#5

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?


#6

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!