FPathFindingQuery ANavigationTestingActor::BuildPathFindingQuery(const ANavigationTestingActor* Goal) const { check(Goal); if (MyNavData) { return FPathFindingQuery(this, *MyNavData, GetNavAgentLocation(), Goal->GetNavAgentLocation(), UNavigationQueryFilter::GetQueryFilter(*MyNavData, FilterClass)); } return FPathFindingQuery(); }
bool UNavigationComponent::AsyncGeneratePath(const FVector& FromLocation, const FVector& GoalLocation, TSharedPtr<const FNavigationQueryFilter> QueryFilter) { if (GetWorld()->GetNavigationSystem() == NULL || GetOuter() == NULL || MyNavAgent == NULL || GetNavData() == NULL) { return false; } // Make sure we're trying to path to the closest valid location TO that location rather than the absolute location. // After talking with Steve P., if we need to ever allow pathing WITHOUT projecting to nav-mesh, it will probably be // best to do so using a flag while keeping this as the default behavior. NOTE: If any changes to this behavior // are made, you should search for other places in UNavigationComponent using NavMeshGoalLocation and make sure the // behavior remains consistent. const FNavAgentProperties* NavAgentProps = MyNavAgent->GetNavAgentProperties(); if (NavAgentProps != NULL) { FVector NavMeshGoalLocation; if (ProjectPointToNavigation(GoalLocation, NavMeshGoalLocation) == QuerySuccess) { const EPathFindingMode::Type Mode = bDoHierarchicalPathfinding ? EPathFindingMode::Hierarchical : EPathFindingMode::Regular; AsynPathQueryID = GetWorld()->GetNavigationSystem()->FindPathAsync(*MyNavAgent->GetNavAgentProperties() , FPathFindingQuery(MyNavData, FromLocation, NavMeshGoalLocation, QueryFilter) , FNavPathQueryDelegate::CreateUObject(this, &UNavigationComponent::AsyncGeneratePath_OnCompleteCallback) , Mode); } else { // projecting destination point failed AsynPathQueryID = INVALID_NAVQUERYID; UE_VLOG(GetOwner(), LogNavigation, Warning, TEXT("AI trying to generate path to point off of navmesh")); UE_VLOG_LOCATION(GetOwner(), GoalLocation, 30, FColor::Red, TEXT("Invalid pathing GoalLocation")); if (MyNavData != NULL) { UE_VLOG_BOX(GetOwner(), FBox(GoalLocation-MyNavData->GetDefaultQueryExtent(),GoalLocation+MyNavData->GetDefaultQueryExtent()), FColor::Red, TEXT_EMPTY); } } } else { AsynPathQueryID = INVALID_NAVQUERYID; } return AsynPathQueryID != INVALID_NAVQUERYID; }
bool AAIController::BuildPathfindingQuery(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query) const { bool bResult = false; UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld()); const ANavigationData* NavData = (NavSys == nullptr) ? nullptr : MoveRequest.IsUsingPathfinding() ? NavSys->GetNavDataForProps(GetNavAgentPropertiesRef()) : NavSys->GetAbstractNavData(); if (NavData) { FVector GoalLocation = MoveRequest.GetGoalLocation(); if (MoveRequest.IsMoveToActorRequest()) { const INavAgentInterface* NavGoal = Cast<const INavAgentInterface>(MoveRequest.GetGoalActor()); if (NavGoal) { const FVector Offset = NavGoal->GetMoveGoalOffset(this); GoalLocation = FQuatRotationTranslationMatrix(MoveRequest.GetGoalActor()->GetActorQuat(), NavGoal->GetNavAgentLocation()).TransformPosition(Offset); } else { GoalLocation = MoveRequest.GetGoalActor()->GetActorLocation(); } } FSharedConstNavQueryFilter NavFilter = UNavigationQueryFilter::GetQueryFilter(*NavData, this, MoveRequest.GetNavigationFilter()); Query = FPathFindingQuery(*this, *NavData, GetNavAgentLocation(), GoalLocation, NavFilter); Query.SetAllowPartialPaths(MoveRequest.IsUsingPartialPaths()); if (PathFollowingComponent) { PathFollowingComponent->OnPathfindingQuery(Query); } bResult = true; } else { UE_VLOG(this, LogAINavigation, Warning, TEXT("Unable to find NavigationData instance while calling AAIController::BuildPathfindingQuery")); } return bResult; }
void UNavigationComponent::OnSmartLinkBroadcast(class USmartNavLinkComponent* NearbyLink) { // update only when agent is actually moving if (NearbyLink == NULL || !Path.IsValid() || PathFollowComp == NULL || PathFollowComp->GetStatus() == EPathFollowingStatus::Idle) { return; } UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld()); if (NavSys == NULL || MyNavAgent == NULL || GetNavData() == NULL) { return; } const bool bHasLink = Path->ContainsSmartLink(NearbyLink); const bool bIsEnabled = NearbyLink->IsEnabled(); if (bIsEnabled == bHasLink) { // enabled link, path already use it - or - disabled link and path it's not using it return; } const FVector GoalLocation = Path->PathPoints.Last().Location; FPathFindingResult Result = NavSys->FindPathSync(*MyNavAgent->GetNavAgentProperties(), FPathFindingQuery(GetNavData(), MyNavAgent->GetNavAgentLocation(), GoalLocation, StoredQueryFilter), bDoHierarchicalPathfinding ? EPathFindingMode::Hierarchical : EPathFindingMode::Regular); if (Result.IsSuccessful() || Result.IsPartial()) { const bool bNewHasLink = Result.Path->ContainsSmartLink(NearbyLink); if ((bIsEnabled && !bHasLink && bNewHasLink) || (!bIsEnabled && bHasLink && !bNewHasLink)) { SetPath(Result.Path); NotifyPathUpdate(); } } }
bool UNavigationComponent::GeneratePath(const FVector& FromLocation, const FVector& GoalLocation, TSharedPtr<const FNavigationQueryFilter> QueryFilter) { if (GetWorld() == NULL || GetWorld()->GetNavigationSystem() == NULL || GetOuter() == NULL || MyNavAgent == NULL || GetNavData() == NULL) { return false; } const FNavLocation NavMeshGoalLocation = ProjectPointToNavigation(GoalLocation); const EPathFindingMode::Type Mode = bDoHierarchicalPathfinding ? EPathFindingMode::Hierarchical : EPathFindingMode::Regular; FPathFindingResult Result = GetWorld()->GetNavigationSystem()->FindPathSync(*MyNavAgent->GetNavAgentProperties() , FPathFindingQuery(GetNavData(), FromLocation, NavMeshGoalLocation.Location, QueryFilter) , Mode); if (Result.IsSuccessful() || Result.IsPartial()) { CurrentGoal = NavMeshGoalLocation.Location; SetPath(Result.Path); return true; } return false; }
bool UBTDecorator_DoesPathExist::CalculateRawConditionValue(UBehaviorTreeComponent* OwnerComp, uint8* NodeMemory) const { const UBlackboardComponent* BlackboardComp = OwnerComp->GetBlackboardComponent(); if (BlackboardComp == NULL) { return false; } FVector PointA = FVector::ZeroVector; FVector PointB = FVector::ZeroVector; const bool bHasPointA = BlackboardComp->GetLocationFromEntry(BlackboardKeyA.GetSelectedKeyID(), PointA); const bool bHasPointB = BlackboardComp->GetLocationFromEntry(BlackboardKeyB.GetSelectedKeyID(), PointB); bool bHasPath = false; const UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(OwnerComp->GetWorld()); if (NavSys && bHasPointA && bHasPointB) { const AAIController* AIOwner = OwnerComp->GetAIOwner(); const ANavigationData* NavData = AIOwner && AIOwner->NavComponent ? AIOwner->NavComponent->GetNavData() : NULL; TSharedPtr<const FNavigationQueryFilter> QueryFilter = UNavigationQueryFilter::GetQueryFilter(NavData, FilterClass); if (PathQueryType == EPathExistanceQueryType::NavmeshRaycast2D) { #if WITH_RECAST const ARecastNavMesh* RecastNavMesh = Cast<const ARecastNavMesh>(NavData); bHasPath = RecastNavMesh && RecastNavMesh->IsSegmentOnNavmesh(PointA, PointB, QueryFilter); #endif } else { EPathFindingMode::Type TestMode = (PathQueryType == EPathExistanceQueryType::HierarchicalQuery) ? EPathFindingMode::Hierarchical : EPathFindingMode::Regular; bHasPath = NavSys->TestPathSync(FPathFindingQuery(AIOwner, NavData, PointA, PointB, QueryFilter), TestMode); } } return bHasPath; }
bool AAIController::PreparePathfinding(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query) { UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld()); if (NavSys) { ANavigationData* NavData = MoveRequest.IsUsingPathfinding() ? NavSys->GetNavDataForProps(GetNavAgentPropertiesRef()) : NavSys->GetAbstractNavData(); FVector GoalLocation = MoveRequest.GetGoalLocation(); if (MoveRequest.HasGoalActor()) { const INavAgentInterface* NavGoal = Cast<const INavAgentInterface>(MoveRequest.GetGoalActor()); if (NavGoal) { const FVector Offset = NavGoal->GetMoveGoalOffset(this); GoalLocation = FRotationTranslationMatrix(MoveRequest.GetGoalActor()->GetActorRotation(), NavGoal->GetNavAgentLocation()).TransformPosition(Offset); } else { GoalLocation = MoveRequest.GetGoalActor()->GetActorLocation(); } } Query = FPathFindingQuery(this, NavData, GetNavAgentLocation(), GoalLocation, UNavigationQueryFilter::GetQueryFilter(NavData, MoveRequest.GetNavigationFilter())); Query.SetAllowPartialPaths(MoveRequest.IsUsingPartialPaths()); if (PathFollowingComponent) { PathFollowingComponent->OnPathfindingQuery(Query); } return true; } return false; }
bool AAIController::PreparePathfinding(FPathFindingQuery& Query, const FVector& Dest, AActor* Goal, bool bUsePathfinding, TSubclassOf<class UNavigationQueryFilter> FilterClass) { UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld()); if (NavSys) { ANavigationData* NavData = bUsePathfinding ? NavSys->GetNavDataForProps(GetNavAgentPropertiesRef()) : NavSys->GetAbstractNavData(); FVector GoalLocation = Dest; if (Goal) { const INavAgentInterface* NavGoal = Cast<const INavAgentInterface>(Goal); if (NavGoal) { const FVector Offset = NavGoal->GetMoveGoalOffset(this); GoalLocation = FRotationTranslationMatrix(Goal->GetActorRotation(), NavGoal->GetNavAgentLocation()).TransformPosition(Offset); } else { GoalLocation = Goal->GetActorLocation(); } } Query = FPathFindingQuery(this, NavData, GetNavAgentLocation(), GoalLocation, UNavigationQueryFilter::GetQueryFilter(NavData, FilterClass)); if (PathFollowingComponent) { PathFollowingComponent->OnPathfindingQuery(Query); } return true; } return false; }
void AOrionRandomWaveSpawner::SpawnWave(int32 TypesToSpawn[SPAWN_NUM], AActor *Focus) { if (Role != ROLE_Authority) return; if (GetWorld() == nullptr || GetWorld()->GetNavigationSystem() == nullptr) return; AOrionGRI *GRI = Cast<AOrionGRI>(GetWorld()->GameState); if (GRI && GRI->bSideMission) FocusActor = this; else FocusActor = Focus; //FailedToSpawn.Empty(); AOrionGameMode *Game = Cast<AOrionGameMode>(GetWorld()->GetAuthGameMode()); for (int32 i = 0; i < SPAWN_NUM; i++) { ////if (!ClassEnabled[i]) //// continue; //possible error checking ////TypesToSpawn[i] = FMath::Min(15, TypesToSpawn[i]); for (int32 j = 0; j < TypesToSpawn[i]; j++) { FActorSpawnParameters SpawnInfo; SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding; FVector Loc; FVector vStart = GetWorld()->GetNavigationSystem()->ProjectPointToNavigation(GetWorld(), GetActorLocation(), (ANavigationData *)0, DefaultFilterClass, FVector(100.0f, 100.0f, 100.0f)); Loc = GetWorld()->GetNavigationSystem()->GetRandomPointInNavigableRadius/*GetRandomReachablePointInRadius*/(GetWorld(), vStart, 5000.0f/*SpawnRadius*/, (ANavigationData*)0, DefaultFilterClass); //quick trace to make sure we will be spawning on landscape, don't want dinos spawning on static meshes FCollisionQueryParams TraceParams("DinoHelper", false); TraceParams.bTraceAsyncScene = false; TraceParams.bReturnPhysicalMaterial = false; FHitResult Hit(ForceInit); if (GetWorld()) { GetWorld()->LineTraceSingleByChannel(Hit, Loc + FVector(0.0f, 0.0f, 15.0f), Loc - FVector(0.0f, 0.0f, 200.0f), COLLISION_WEAPON, TraceParams); if (GetWorld()->SweepSingleByChannel(Hit, Loc + FVector(0.0f, 0.0f, 15.0f), Loc - FVector(0.0f, 0.0f, 200.0f), FQuat::Identity, ECollisionChannel::ECC_Pawn, FCollisionShape::MakeSphere(5), TraceParams)) { if (!Cast<ALandscape>(Hit.GetActor())) { Game->SpawnTypes[i]++; continue; } } else { Game->SpawnTypes[i]++; continue; } } FSharedConstNavQueryFilter QueryFilter = UNavigationQueryFilter::GetQueryFilter(GetWorld()->GetNavigationSystem()->MainNavData, DefaultFilterClass); if (!GetWorld()->GetNavigationSystem()->TestPathSync(FPathFindingQuery(nullptr, *GetWorld()->GetNavigationSystem()->MainNavData, vStart, Loc, QueryFilter))) { Game->SpawnTypes[i]++; continue; } bool bExit = false; for (TActorIterator<AOrionPlayerController> Itr(GetWorld()); Itr && !bExit; ++Itr) { AOrionPlayerController *PC = *Itr; AOrionCharacter *P = Cast<AOrionCharacter>(PC->GetPawn()); if (P == nullptr) continue; if ((P->GetActorLocation() - Loc).SizeSquared() < 2250000.0) bExit = true; } if (bExit) { //FailedToSpawn.Add(i); Game->SpawnTypes[i]++; continue; } AOrionCharacter* NewPawn = GetWorld()->SpawnActor<AOrionCharacter>(SpawnClasses[i], Loc + FVector(0, 0, 1.05f) * SpawnClasses[i].GetDefaultObject()->GetCapsuleComponent()->GetScaledCapsuleHalfHeight(), GetActorRotation(), SpawnInfo); if (NewPawn) { if (Game) Game->AddActiveWaveEnemy(NewPawn); NewPawn->bRun = true; //NewPawn->FocusArea = FocusLocation; NewPawn->FocusActor = FocusActor; NewPawn->SpawnDefaultController(); NewPawn->SetAIType(AI_HUNTING); NewPawn->SpawnType = i; //setup the enemies level for ilvl stuff NewPawn->Level = Game->GetEnemyItemLevel(true); //setup health based on ilvl NewPawn->HealthMax = NewPawn->HealthMax * FMath::Pow(LEVELPOWER, NewPawn->Level / LEVELINTERVAL) * 0.1f; NewPawn->Health = NewPawn->HealthMax; //same for shields (robots only) NewPawn->ShieldMax = NewPawn->ShieldMax * FMath::Pow(LEVELPOWER, NewPawn->Level / LEVELINTERVAL) * 0.1f; NewPawn->Shield = NewPawn->ShieldMax; } else if (Game) { //FailedToSpawn.Add(i); Game->SpawnTypes[i]++; continue; } } } /*if (FailedToSpawn.Num() > 0) { GetWorldTimerManager().SetTimer(FailedTimer, this, &AOrionRandomWaveSpawner::SpawnFailures, 1.0f, false); }*/ }