I’m new in C++ and Unreal4. I try to find out if a point is reachable via the Navmash or not.
I’m generating random points in an Area for an Ai. But maybe the point is on a tree or in water….
Sadly I can’t find a tutorial or documentation how the NavigationSystem, NavigationGraph, NavigationComponent, … working together. So I start to stealing code snippets from the API. I know the hole Behavior Tree is still in experimental but maybe you can recommend something.
Now I getting an access violation error at runtime when I try to call GetNavigationSystem?
But also [FONT=Courier New]SpawnActor<ANavigationGraph>() does not feel right too. (But I can store this in a class variable)
[FONT=Courier New]class ANavigationData* NavDataClass = NavData; also does not look right.
And how can I get an Instance to a filter class?
i had kind of similar problems, when doing point&click movement; I wanted to detect if any point i clicked on is outside of the NavMesh and if so, i wanted the character to go straight into that direction instead of NavMesh Navigation.
I couldnt find any method like “IsPointOnNavmesh” or something similar, so i utilized the existing components for finding a path and checking if its a valid one.
You may be able to incorporate something like that:
In your PlayerController .h file, add a NavComponent and a PathFollowingComponent:
private:
/** Component used for pathfinding and querying environment's navigation. */
UPROPERTY()
TSubobjectPtr<class UNavigationComponent> NavComponent;
/** Component used for moving along a path. */
UPROPERTY()
TSubobjectPtr<class UPathFollowingComponent> PathFollowingComponent;
Then we need to initialize them on instantiation of the controller, so in your constructor-method of your .cpp you need to call them.
// set up navigation component
NavComponent = PCIP.CreateDefaultSubobject<UNavigationComponent>(this, TEXT("NavComponent"));
PathFollowingComponent = PCIP.CreateDefaultSubobject<UPathFollowingComponent>(this, TEXT("PathFollowingComponent"));
Then, something like the following method should work for you.
We do not exactly check here if the Point is on the NavMesh, but if the NavigationComponent can actually find a Path to the given destination.
bool AMyPlayerController::IsPointOnNavMesh(FVector* dest) {
bool bFoundPath = NavComponent->FindPathToLocation(dest, NULL);
if (bFoundPath == false || NavComponent->GetPath().IsValid() == false) {
// Point is not on NavMesh or not reachable for some other reason
return false;
}
return true;
}
generally there is no need for a Tutorial with basic pathfinding, since it is quite easy to implement, given there are no such special cases like checking if a point is on a navmesh and stuff
Normally, you use different methods for navigating your playercharacter than you would do with your AI; Though, if you already implemented the 2 components as shown above in your PlayerController (Please note that these are already there for AIControllers!), you can generally use the following:
if (IsPointOnNavMesh(dest)) {
PathFollowComp->RequestMove(NavComponent->GetPath(), NULL, 100.0f);
}
And thats it, now your Characters will follow paths all along.
Btw, i dont know how you generate your random points but….
And for checking if the AI has reached the destination point, just override OnMoveCompleted in your AIController (This event is not there for playercontrollers i think):
void MyAIController::OnMoveCompleted(uint32 RequestID, EPathFollowingResult::Type Result) {
if (Result == EPathFollowingResult::Success) {
// Get the next point for movement, or play an animation for the ai cause its happy it reached the destination…
...
}
}