void UGameplayTask::PauseInTaskQueue() { switch (TaskState) { case EGameplayTaskState::Uninitialized: UE_VLOG(GetGameplayTasksComponent(), LogGameplayTasks, Error , TEXT("UGameplayTask::PauseInTaskQueue Task %s passed for pausing withouth having InitTask called on it!") , *GetName()); break; case EGameplayTaskState::AwaitingActivation: // nothing to do here. Don't change the state to indicate this task has never been run before break; case EGameplayTaskState::Paused: // nothing to do here. Already paused break; case EGameplayTaskState::Active: // pause! Pause(); break; case EGameplayTaskState::Finished: // nothing to do here. But sounds odd, so let's log this, just in case UE_VLOG(GetGameplayTasksComponent(), LogGameplayTasks, Log , TEXT("UGameplayTask::PauseInTaskQueue Task %s being pause while already marked as Finished") , *GetName()); break; default: checkNoEntry(); // looks like unhandled value! Probably a new enum entry has been added break; } }
bool UPawnAction::Activate() { bool bResult = false; UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Activating at priority %s! First start? %s Paused? %s") , *GetName() , *GetPriorityName() , HasBeenStarted() ? TEXT("NO") : TEXT("YES") , IsPaused() ? TEXT("YES") : TEXT("NO")); if (HasBeenStarted() && IsPaused()) { bResult = Resume(); } else { bResult = Start(); if (bResult == false) { UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Failed to start.") , *GetName()); bFailedToStart = true; SetFinishResult(EPawnActionResult::Failed); SendEvent(EPawnActionEventType::FailedToStart); } } return bResult; }
void UAITask_MoveTo::ConditionalUpdatePath() { // mark this path as waiting for repath so that PathFollowingComponent doesn't abort the move while we // micro manage repathing moment // note that this flag fill get cleared upon repathing end if (Path.IsValid()) { Path->SetManualRepathWaiting(true); } if (MoveRequest.IsUsingPathfinding() && OwnerController && OwnerController->ShouldPostponePathUpdates()) { UE_VLOG(GetGameplayTasksComponent(), LogGameplayTasks, Log, TEXT("%s> can't path right now, waiting..."), *GetName()); OwnerController->GetWorldTimerManager().SetTimer(PathRetryTimerHandle, this, &UAITask_MoveTo::ConditionalUpdatePath, 0.2f, false); } else { PathRetryTimerHandle.Invalidate(); ANavigationData* NavData = Path.IsValid() ? Path->GetNavigationDataUsed() : nullptr; if (NavData) { NavData->RequestRePath(Path, ENavPathUpdateType::NavigationChanged); } else { UE_VLOG(GetGameplayTasksComponent(), LogGameplayTasks, Log, TEXT("%s> unable to repath, aborting!"), *GetName()); FinishMoveTask(EPathFollowingResult::Aborted); } } }
bool UPawnAction::Pause(const UPawnAction* PausedBy) { // parent should be paused anyway ensure(ParentAction == NULL || ParentAction->IsPaused() == true); // don't pause twice, this should be guaranteed by the PawnActionsComponent ensure(bPaused == false); if (AbortState == EPawnActionAbortState::LatentAbortInProgress || AbortState == EPawnActionAbortState::AbortDone) { UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Not pausing due to being in unpausable aborting state") , *GetName(), *ChildAction->GetName()); return false; } UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Pausing..."), *GetName()); bPaused = true; if (ChildAction) { ChildAction->Pause(PausedBy); } return bPaused; }
bool AAIController::UseBlackboard(UBlackboardData* BlackboardAsset) { if (BlackboardAsset == NULL) { UE_VLOG(this, LogBehaviorTree, Log, TEXT("UseBlackboard: trying to use NULL Blackboard asset. Ignoring")); return false; } bool bSuccess = true; UBlackboardComponent* BlackboardComp = FindComponentByClass<UBlackboardComponent>(); if (BlackboardComp == NULL) { BlackboardComp = NewObject<UBlackboardComponent>(this, TEXT("BlackboardComponent")); if (BlackboardComp != NULL) { InitializeBlackboard(*BlackboardComp, *BlackboardAsset); BlackboardComp->RegisterComponent(); } } else if (BlackboardComp->GetBlackboardAsset() == NULL) { InitializeBlackboard(*BlackboardComp, *BlackboardAsset); } else if (BlackboardComp->GetBlackboardAsset() != BlackboardAsset) { UE_VLOG(this, LogBehaviorTree, Log, TEXT("UseBlackboard: requested blackboard %s while already has %s instantiated. Forcing new BB.") , *GetNameSafe(BlackboardAsset), *GetNameSafe(BlackboardComp->GetBlackboardAsset())); InitializeBlackboard(*BlackboardComp, *BlackboardAsset); } return bSuccess; }
bool UPawnAction::Resume() { // parent should be paused anyway ensure(ParentAction == NULL || ParentAction->IsPaused() == true); // do not unpause twice if (bPaused == false) { return false; } ensure(ChildAction == NULL); if (ChildAction) { UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Resuming child, %s"), *GetName(), *ChildAction->GetName()); ChildAction->Resume(); } else { UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> Resuming."), *GetName()); bPaused = false; } return !bPaused; }
void UPawnActionsComponent::UpdateAILogicLock() { if (ControlledPawn && ControlledPawn->GetController()) { UBrainComponent* BrainComp = ControlledPawn->GetController()->FindComponentByClass<UBrainComponent>(); if (BrainComp) { if (CurrentAction != NULL && CurrentAction->GetPriority() > EAIRequestPriority::Logic) { UE_VLOG(ControlledPawn, LogPawnAction, Log, TEXT("Locking AI logic")); BrainComp->LockResource(EAIRequestPriority::HardScript); bLockedAILogic = true; } else if (bLockedAILogic) { UE_VLOG(ControlledPawn, LogPawnAction, Log, TEXT("Clearing AI logic lock")); bLockedAILogic = false; BrainComp->ClearResourceLock(EAIRequestPriority::HardScript); if (BrainComp->IsResourceLocked() == false) { UE_VLOG(ControlledPawn, LogPawnAction, Log, TEXT("Reseting AI logic")); BrainComp->RestartLogic(); } // @todo consider checking if lock priority is < Logic else { UE_VLOG(ControlledPawn, LogPawnAction, Log, TEXT("AI logic still locked with other priority")); BrainComp->RequestLogicRestartOnUnlock(); } } } } }
bool UPawnActionsComponent::OnEvent(UPawnAction& Action, EPawnActionEventType::Type Event) { bool bResult = false; const FPawnActionEvent ActionEvent(Action, Event, ActionEventIndex++); if (Event != EPawnActionEventType::Invalid && ActionEvents.Find(ActionEvent) == INDEX_NONE) { ActionEvents.Add(ActionEvent); // if it's a first even enable tick if (ActionEvents.Num() == 1) { SetComponentTickEnabled(true); } bResult = true; } else if (Event == EPawnActionEventType::Invalid) { // ignore UE_VLOG(ControlledPawn, LogPawnAction, Warning, TEXT("Ignoring Action Event: Action %s Event %s") , *Action.GetName(), *GetEventName(Event)); } else { UE_VLOG(ControlledPawn, LogPawnAction, Warning, TEXT("Ignoring duplicate Action Event: Action %s Event %s") , *Action.GetName(), *GetEventName(Event)); } return bResult; }
void UHTNPlannerComponent::StopPlanner(EHTNStopMode StopMode) { if(!bRequestedStop) { bRequestedStop = true; if(ActiveTask.IsValid()) { // remove all observers before requesting abort UnregisterMessageObserversFrom(ActiveTask); UE_VLOG(GetOwner(), LogHTNPlanner, Log, TEXT("Abort task: %s"), *UHTNPlannerTypes::DescribeTaskHelper(ActiveTask->Task, ActiveTask->GetMemory())); if(UPrimitiveTask* PrimitiveTask = Cast<UPrimitiveTask>(ActiveTask->Task)) { EHTNExecutionResult TaskResult = PrimitiveTask->AbortTask(*this, ActiveTask->GetMemory()); if(TaskResult == EHTNExecutionResult::InProgress) { bWaitingForAbortingTasks = true; } if(ActiveTask.IsValid()) { OnTaskFinished(ActiveTask, TaskResult); } } } } if(bWaitingForAbortingTasks) { if(StopMode == EHTNStopMode::Safe) { UE_VLOG(GetOwner(), LogHTNPlanner, Log, TEXT("StopPlanner is waiting for aborting tasks to finish...")); UE_LOG(LogHTNPlanner, Warning, TEXT("StopPlanner is waiting for aborting tasks to finish...")); return; } UE_VLOG(GetOwner(), LogHTNPlanner, Warning, TEXT("StopPlanner was forced while waiting for tasks to finish aborting!")); } ActiveTask = nullptr; PendingExecution = nullptr; PlanningStack.Empty(); PastStreakStacks.Empty(); StreakEndedQueues.Empty(); StreakStacks.Empty(); RegisteredServices.Empty(); TaskMessageObservers.Empty(); NumStackElements = 0; // make sure to allow new execution requests bRequestedExecutionUpdate = false; bRequestedStop = false; bIsRunning = false; }
void UGameplayTasksComponent::ProcessTaskEvents() { static const int32 MaxIterations = 16; bInEventProcessingInProgress = true; int32 IterCounter = 0; while (TaskEvents.Num() > 0) { IterCounter++; if (IterCounter > MaxIterations) { UE_VLOG(this, LogGameplayTasks, Error, TEXT("UGameplayTasksComponent::ProcessTaskEvents has exceeded allowes number of iterations. Check your GameplayTasks for logic loops!")); break; } for (int32 EventIndex = 0; EventIndex < TaskEvents.Num(); ++EventIndex) { UE_VLOG(this, LogGameplayTasks, Verbose, TEXT("UGameplayTasksComponent::ProcessTaskEvents: %s event %s") , *TaskEvents[EventIndex].RelatedTask.GetName(), GetGameplayTaskEventName(TaskEvents[EventIndex].Event)); if (TaskEvents[EventIndex].RelatedTask.IsPendingKill()) { UE_VLOG(this, LogGameplayTasks, Verbose, TEXT("%s is PendingKill"), *TaskEvents[EventIndex].RelatedTask.GetName()); // we should ignore it, but just in case run the removal code. RemoveTaskFromPriorityQueue(TaskEvents[EventIndex].RelatedTask); continue; } switch (TaskEvents[EventIndex].Event) { case EGameplayTaskEvent::Add: if (TaskEvents[EventIndex].RelatedTask.TaskState != EGameplayTaskState::Finished) { AddTaskToPriorityQueue(TaskEvents[EventIndex].RelatedTask); } else { UE_VLOG(this, LogGameplayTasks, Error, TEXT("UGameplayTasksComponent::ProcessTaskEvents trying to add a finished task to priority queue!")); } break; case EGameplayTaskEvent::Remove: RemoveTaskFromPriorityQueue(TaskEvents[EventIndex].RelatedTask); break; default: checkNoEntry(); break; } } TaskEvents.Reset(); UpdateTaskActivations(); // task activation changes may create new events, loop over to check it } bInEventProcessingInProgress = false; }
void AFunctionalTest::FinishTest(TEnumAsByte<EFunctionalTestResult::Type> TestResult, const FString& Message) { const static UEnum* FTestResultTypeEnum = FindObject<UEnum>( NULL, TEXT("FunctionalTesting.FunctionalTest.EFunctionalTestResult") ); bIsRunning = false; SetActorTickEnabled(false); OnTestFinished.Broadcast(); AActor** ActorToDestroy = AutoDestroyActors.GetTypedData(); for (int32 ActorIndex = 0; ActorIndex < AutoDestroyActors.Num(); ++ActorIndex, ++ActorToDestroy) { if (*ActorToDestroy != NULL) { // will be removed next frame (*ActorToDestroy)->SetLifeSpan( 0.01f ); } } const FText ResultText = FTestResultTypeEnum->GetEnumText( TestResult.GetValue() ); const FString OutMessage = FString::Printf(TEXT("%s> Result: %s> %s") , *GetActorLabel() , *ResultText.ToString() , Message.IsEmpty() == false ? *Message : TEXT("Test finished") ); AutoDestroyActors.Reset(); EMessageSeverity::Type MessageLogSeverity = EMessageSeverity::Info; switch (TestResult.GetValue()) { case EFunctionalTestResult::Invalid: case EFunctionalTestResult::Error: UE_VLOG(this, LogFunctionalTest, Error, TEXT("%s"), *OutMessage); MessageLogSeverity = EMessageSeverity::Error; break; case EFunctionalTestResult::Running: UE_VLOG(this, LogFunctionalTest, Warning, TEXT("%s"), *OutMessage); MessageLogSeverity = EMessageSeverity::Warning; break; case EFunctionalTestResult::Failed: UE_VLOG(this, LogFunctionalTest, Error, TEXT("%s"), *OutMessage); MessageLogSeverity = EMessageSeverity::Error; break; default: UE_VLOG(this, LogFunctionalTest, Log, TEXT("%s"), *OutMessage); break; } FMessageLog("FunctionalTestingLog").Message(MessageLogSeverity, FText::FromString(GetActorLabel())) ->AddToken( FTextToken::Create( ResultText ) ) ->AddToken( FTextToken::Create( Message.IsEmpty() == false ? FText::FromString(Message) : NSLOCTEXT("FunctionalTest", "FinishedTest", "Test finished") ) ); TestFinishedObserver.ExecuteIfBound(this); }
void UPawnActionsComponent::UpdateCurrentAction() { UE_VLOG(ControlledPawn, LogPawnAction, Log, TEXT("Picking new current actions. Old CurrentAction %s") , *GetActionSignature(CurrentAction)); // find the highest priority action available UPawnAction* NewCurrentAction = NULL; int32 Priority = EAIRequestPriority::MAX - 1; do { NewCurrentAction = ActionStacks[Priority].GetTop(); } while (NewCurrentAction == NULL && --Priority >= 0); // if it's a new Action then enable it if (CurrentAction != NewCurrentAction) { UE_VLOG(ControlledPawn, LogPawnAction, Log, TEXT("New action: %s") , *GetActionSignature(NewCurrentAction)); if (CurrentAction != NULL && CurrentAction->IsActive()) { CurrentAction->Pause(NewCurrentAction); } CurrentAction = NewCurrentAction; bool bNewActionStartedSuccessfully = true; if (CurrentAction != NULL) { bNewActionStartedSuccessfully = CurrentAction->Activate(); } if (bNewActionStartedSuccessfully == false) { UE_VLOG(ControlledPawn, LogPawnAction, Warning, TEXT("CurrentAction %s failed to activate. Removing and re-running action selection") , *GetActionSignature(NewCurrentAction)); CurrentAction = NULL; } // @HACK temporary solution to have actions and old BT tasks work together else if (CurrentAction == NULL || CurrentAction->GetPriority() != EAIRequestPriority::Logic) { UpdateAILogicLock(); } } else { if (CurrentAction == NULL) { UpdateAILogicLock(); } else { UE_VLOG(ControlledPawn, LogPawnAction, Warning, TEXT("Still doing the same action")); } } }
void UGameplayTask::OnGameplayTaskInitialized(UGameplayTask& Task) { UE_VLOG(GetGameplayTasksComponent(), LogGameplayTasks, Verbose, TEXT("%s> Child task initialized: %s"), *GetName(), *Task.GetName()); // only one child task is allowed if (ChildTask) { UE_VLOG(GetGameplayTasksComponent(), LogGameplayTasks, Verbose, TEXT(">> terminating previous child task: %s"), *ChildTask->GetName()); ChildTask->EndTask(); } ChildTask = &Task; }
EPathFollowingRequestResult::Type AAIController::MoveToActor(AActor* Goal, float AcceptanceRadius, bool bStopOnOverlap, bool bUsePathfinding, bool bCanStrafe, TSubclassOf<UNavigationQueryFilter> FilterClass) { SCOPE_CYCLE_COUNTER(STAT_MoveToActor); EPathFollowingRequestResult::Type Result = EPathFollowingRequestResult::Failed; UE_VLOG(this, LogAINavigation, Log, TEXT("MoveToActor: Goal(%s) AcceptRadius(%.1f%s) bUsePathfinding(%d) bCanStrafe(%d) Filter(%s)"), *GetNameSafe(Goal), AcceptanceRadius, bStopOnOverlap ? TEXT(" + agent") : TEXT(""), bUsePathfinding, bCanStrafe, *GetNameSafe(FilterClass)); if (Goal) { if (PathFollowingComponent && PathFollowingComponent->HasReached(*Goal, AcceptanceRadius, !bStopOnOverlap)) { UE_VLOG(this, LogAINavigation, Log, TEXT("MoveToActor: already at goal!")); // make sure previous move request gets aborted PathFollowingComponent->AbortMove(TEXT("Aborting move due to new move request finishing with AlreadyAtGoal"), FAIRequestID::AnyRequest); PathFollowingComponent->SetLastMoveAtGoal(true); OnMoveCompleted(FAIRequestID::CurrentRequest, EPathFollowingResult::Success); Result = EPathFollowingRequestResult::AlreadyAtGoal; } else { FPathFindingQuery Query; const bool bValidQuery = PreparePathfinding(Query, Goal->GetActorLocation(), Goal, bUsePathfinding, FilterClass); const FAIRequestID RequestID = bValidQuery ? RequestPathAndMove(Query, Goal, AcceptanceRadius, bStopOnOverlap, NULL) : FAIRequestID::InvalidRequest; if (RequestID.IsValid()) { bAllowStrafe = bCanStrafe; Result = EPathFollowingRequestResult::RequestSuccessful; } } } if (Result == EPathFollowingRequestResult::Failed) { if (PathFollowingComponent) { PathFollowingComponent->SetLastMoveAtGoal(false); } OnMoveCompleted(FAIRequestID::InvalidRequest, EPathFollowingResult::Invalid); } return Result; }
FVector UEnvQueryGenerator_OnCircle::CalcDirection(FEnvQueryInstance& QueryInstance) const { AActor* Querier = Cast<AActor>(QueryInstance.Owner.Get()); check(Querier != NULL); FVector Direction; if (bDefineArc) { // By default, use Querier rotation for arc direction. Direction = Querier->GetActorForwardVector(); if (ArcDirection.DirMode == EEnvDirection::TwoPoints) { TArray<FVector> Start; TArray<FVector> End; QueryInstance.PrepareContext(ArcDirection.LineFrom, Start); QueryInstance.PrepareContext(ArcDirection.LineTo, End); if (Start.Num() > 0 && End.Num() > 0) { Direction = (End[0] - Start[0]).GetSafeNormal(); } else { UE_VLOG(Querier, LogEQS, Warning, TEXT("UEnvQueryGenerator_OnCircle::CalcDirection failed to calc direction in %s. Using querier facing."), *QueryInstance.QueryName); } } else { TArray<FRotator> Rot; QueryInstance.PrepareContext(ArcDirection.Rotation, Rot); if (Rot.Num() > 0) { Direction = Rot[0].Vector(); } else { UE_VLOG(Querier, LogEQS, Warning, TEXT("UEnvQueryGenerator_OnCircle::CalcDirection failed to calc direction in %s. Using querier facing."), *QueryInstance.QueryName); } } } else { // Don't rotate based on querier! Instead, use a stable rotation so the points on the circle don't rotate! Direction = FVector(1, 0, 0); } return Direction; }
void FBehaviorTreeInstance::DeactivateNodes(FBehaviorTreeSearchData& SearchData, uint16 InstanceIndex) { for (int32 Idx = SearchData.PendingUpdates.Num() - 1; Idx >= 0; Idx--) { FBehaviorTreeSearchUpdate& UpdateInfo = SearchData.PendingUpdates[Idx]; if (UpdateInfo.InstanceIndex == InstanceIndex && UpdateInfo.Mode == EBTNodeUpdateMode::Add) { UE_VLOG(SearchData.OwnerComp.GetOwner(), LogBehaviorTree, Verbose, TEXT("Search node update[%s]: %s"), *UBehaviorTreeTypes::DescribeNodeUpdateMode(EBTNodeUpdateMode::Remove), *UBehaviorTreeTypes::DescribeNodeHelper(UpdateInfo.AuxNode ? (UBTNode*)UpdateInfo.AuxNode : (UBTNode*)UpdateInfo.TaskNode)); SearchData.PendingUpdates.RemoveAt(Idx, 1, false); } } for (int32 Idx = 0; Idx < ParallelTasks.Num(); Idx++) { const FBehaviorTreeParallelTask& ParallelTask = ParallelTasks[Idx]; if (ParallelTask.TaskNode && ParallelTask.Status == EBTTaskStatus::Active) { SearchData.AddUniqueUpdate(FBehaviorTreeSearchUpdate(ParallelTask.TaskNode, InstanceIndex, EBTNodeUpdateMode::Remove)); } } for (int32 Idx = 0; Idx < ActiveAuxNodes.Num(); Idx++) { if (ActiveAuxNodes[Idx]) { SearchData.AddUniqueUpdate(FBehaviorTreeSearchUpdate(ActiveAuxNodes[Idx], InstanceIndex, EBTNodeUpdateMode::Remove)); } } }
void FBehaviorTreeSearchData::AddUniqueUpdate(const FBehaviorTreeSearchUpdate& UpdateInfo) { UE_VLOG(OwnerComp.GetOwner(), LogBehaviorTree, Verbose, TEXT("Search node update[%s]: %s"), *UBehaviorTreeTypes::DescribeNodeUpdateMode(UpdateInfo.Mode), *UBehaviorTreeTypes::DescribeNodeHelper(UpdateInfo.AuxNode ? (UBTNode*)UpdateInfo.AuxNode : (UBTNode*)UpdateInfo.TaskNode)); bool bSkipAdding = false; for (int32 UpdateIndex = 0; UpdateIndex < PendingUpdates.Num(); UpdateIndex++) { const FBehaviorTreeSearchUpdate& Info = PendingUpdates[UpdateIndex]; if (Info.AuxNode == UpdateInfo.AuxNode && Info.TaskNode == UpdateInfo.TaskNode) { // duplicate, skip if (Info.Mode == UpdateInfo.Mode) { bSkipAdding = true; break; } // don't add pairs add-remove bSkipAdding = (Info.Mode == EBTNodeUpdateMode::Remove) || (UpdateInfo.Mode == EBTNodeUpdateMode::Remove); PendingUpdates.RemoveAt(UpdateIndex, 1, false); } } if (!bSkipAdding) { const int32 Idx = PendingUpdates.Add(UpdateInfo); PendingUpdates[Idx].bPostUpdate = (UpdateInfo.Mode == EBTNodeUpdateMode::Add) && (Cast<UBTService>(UpdateInfo.AuxNode) != NULL); } }
void UCrowdFollowingComponent::FollowPathSegment(float DeltaTime) { if (!bEnableCrowdSimulation) { Super::FollowPathSegment(DeltaTime); return; } if (bUpdateDirectMoveVelocity && DestinationActor.IsValid()) { const FVector CurrentTargetPt = DestinationActor->GetActorLocation(); const float DistSq = (CurrentTargetPt - GetCurrentTargetLocation()).SizeSquared(); if (DistSq > FMath::Square(10.0f)) { UCrowdManager* Manager = UCrowdManager::GetCurrent(GetWorld()); const FVector AgentLoc = GetCrowdAgentLocation(); CurrentDestination.Set(Path->GetBaseActor(), CurrentTargetPt); CrowdAgentMoveDirection = (CurrentTargetPt - AgentLoc).GetSafeNormal(); MoveSegmentDirection = CrowdAgentMoveDirection; Manager->SetAgentMoveDirection(this, MoveSegmentDirection); UE_VLOG(GetOwner(), LogCrowdFollowing, Log, TEXT("Updated direct move direction for crowd agent.")); } } UpdateMoveFocus(); }
void UCrowdFollowingComponent::OnNavNodeChanged(NavNodeRef NewPolyRef, NavNodeRef PrevPolyRef, int32 CorridorSize) { if (bEnableCrowdSimulation && Status != EPathFollowingStatus::Idle) { // update last visited path poly FNavMeshPath* NavPath = Path.IsValid() ? Path->CastPath<FNavMeshPath>() : NULL; if (NavPath) { for (int32 Idx = LastPathPolyIndex; Idx < NavPath->PathCorridor.Num(); Idx++) { if (NavPath->PathCorridor[Idx] == NewPolyRef) { LastPathPolyIndex = Idx; break; } } } UE_VLOG(GetOwner(), LogCrowdFollowing, Verbose, TEXT("OnNavNodeChanged, CorridorSize:%d, LastVisitedIndex:%d"), CorridorSize, LastPathPolyIndex); const bool bSwitchPart = ShouldSwitchPathPart(CorridorSize); if (bSwitchPart && !bFinalPathPart) { SwitchToNextPathPart(); } } }
void UCrowdFollowingComponent::FollowPathSegment(float DeltaTime) { if (!bEnableCrowdSimulation) { Super::FollowPathSegment(DeltaTime); return; } if (bUpdateDirectMoveVelocity) { const FVector CurrentTargetPt = DestinationActor.IsValid() ? DestinationActor->GetActorLocation() : GetCurrentTargetLocation(); const FVector AgentLoc = GetCrowdAgentLocation(); const FVector NewDirection = (CurrentTargetPt - AgentLoc).GetSafeNormal(); const bool bDirectionChanged = !NewDirection.Equals(CrowdAgentMoveDirection); if (bDirectionChanged) { CurrentDestination.Set(Path->GetBaseActor(), CurrentTargetPt); CrowdAgentMoveDirection = NewDirection; MoveSegmentDirection = NewDirection; UCrowdManager* Manager = UCrowdManager::GetCurrent(GetWorld()); Manager->SetAgentMoveDirection(this, NewDirection); UE_VLOG(GetOwner(), LogCrowdFollowing, Log, TEXT("Updated direct move direction for crowd agent.")); } } UpdateMoveFocus(); }
FAIRequestID AAIController::RequestPathAndMove(FPathFindingQuery& Query, AActor* Goal, float AcceptanceRadius, bool bStopOnOverlap, FCustomMoveSharedPtr CustomData) { FAIRequestID RequestID; UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld()); if (NavSys) { FPathFindingResult PathResult = NavSys->FindPathSync(Query); if (PathResult.Result != ENavigationQueryResult::Error) { if (PathResult.IsSuccessful() && PathResult.Path.IsValid()) { if (Goal) { PathResult.Path->SetGoalActorObservation(*Goal, 100.0f); } PathResult.Path->EnableRecalculationOnInvalidation(true); } RequestID = RequestMove(PathResult.Path, Goal, AcceptanceRadius, bStopOnOverlap, CustomData); } else { UE_VLOG(this, LogBehaviorTree, Error, TEXT("Trying to find path to %s resulted in Error"), *GetNameSafe(Goal)); } } return RequestID; }
bool UPawnAction_Repeat::PushSubAction() { if (ActionToRepeat == NULL) { Finish(EPawnActionResult::Failed); return false; } else if (RepeatsLeft == 0) { Finish(EPawnActionResult::Success); return true; } if (RepeatsLeft > 0) { --RepeatsLeft; } UPawnAction* ActionCopy = SubActionTriggeringPolicy == EPawnSubActionTriggeringPolicy::CopyBeforeTriggering ? Cast<UPawnAction>(StaticDuplicateObject(ActionToRepeat, this, NULL)) : ActionToRepeat; UE_VLOG(GetPawn(), LogPawnAction, Log, TEXT("%s> pushing repeted action %s %s, repeats left: %d") , *GetName(), SubActionTriggeringPolicy == EPawnSubActionTriggeringPolicy::CopyBeforeTriggering ? TEXT("copy") : TEXT("instance") , *GetNameSafe(ActionCopy), RepeatsLeft); check(ActionCopy); RecentActionCopy = ActionCopy; return PushChildAction(*ActionCopy); }
//@todo add "warning" level here void AFunctionalTest::LogMessage(const FString& Message) { UFunctionalTestingManager::AddLogItem(FText::FromString(Message)); UE_VLOG(this, LogFunctionalTest, Log , TEXT("%s> %s") , *GetActorLabel(), *Message); }
void UAISense_Sight::CleanseInvalidSources() { bool bInvalidSourcesFound = false; for (TMap<FName, FAISightTarget>::TIterator ItTarget(ObservedTargets); ItTarget; ++ItTarget) { if (ItTarget->Value.Target.IsValid() == false) { // remove affected queries RemoveAllQueriesToTarget(ItTarget->Key, DontSort); // remove target itself ItTarget.RemoveCurrent(); bInvalidSourcesFound = true; } } if (bInvalidSourcesFound) { // remove holes ObservedTargets.Compact(); SortQueries(); } else { UE_VLOG(GetPerceptionSystem(), LogAIPerception, Error, TEXT("UAISense_Sight::CleanseInvalidSources called and no invalid targets were found")); } }
void AAIController::FindPathForMoveRequest(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query, FNavPathSharedPtr& OutPath) const { SCOPE_CYCLE_COUNTER(STAT_AI_Overall); UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld()); if (NavSys) { FPathFindingResult PathResult = NavSys->FindPathSync(Query); if (PathResult.Result != ENavigationQueryResult::Error) { if (PathResult.IsSuccessful() && PathResult.Path.IsValid()) { if (MoveRequest.IsMoveToActorRequest()) { PathResult.Path->SetGoalActorObservation(*MoveRequest.GetGoalActor(), 100.0f); } PathResult.Path->EnableRecalculationOnInvalidation(true); OutPath = PathResult.Path; } } else { UE_VLOG(this, LogAINavigation, Error, TEXT("Trying to find path to %s resulted in Error") , MoveRequest.IsMoveToActorRequest() ? *GetNameSafe(MoveRequest.GetGoalActor()) : *MoveRequest.GetGoalLocation().ToString()); UE_VLOG_SEGMENT(this, LogAINavigation, Error, GetPawn() ? GetPawn()->GetActorLocation() : FAISystem::InvalidLocation , MoveRequest.GetGoalLocation(), FColor::Red, TEXT("Failed move to %s"), *GetNameSafe(MoveRequest.GetGoalActor())); } } }
void UHTNPlannerComponent::UnregisterMessageObserversFrom(const TSharedPtr<FHTNTaskInstance>& TaskInstance) { if(TaskInstance.IsValid()) { int32 NumRemoved = 0; for(int32 Idx = 0; Idx < TaskMessageObservers.Num(); /**/) { if(TaskMessageObservers[Idx].TaskInstance == TaskInstance) { // found a message observer registered for our task TaskMessageObservers.RemoveAtSwap(Idx, 1); ++NumRemoved; // don't need to increment index since we removed an element } else { ++Idx; } } UE_VLOG(GetOwner(), LogHTNPlanner, Log, TEXT("Message observers removed for task[%s] (num:%d)"), *UHTNPlannerTypes::DescribeTaskHelper(TaskInstance->Task, TaskInstance->GetMemory()), NumRemoved); } }
//----------------------------------------------------------------------// // GameplayTasksComponent-related functions //----------------------------------------------------------------------// void UGameplayTask::ActivateInTaskQueue() { switch(TaskState) { case EGameplayTaskState::Uninitialized: UE_VLOG(GetGameplayTasksComponent(), LogGameplayTasks, Error , TEXT("UGameplayTask::ActivateInTaskQueue Task %s passed for activation withouth having InitTask called on it!") , *GetName()); break; case EGameplayTaskState::AwaitingActivation: PerformActivation(); break; case EGameplayTaskState::Paused: // resume Resume(); break; case EGameplayTaskState::Active: // nothing to do here break; case EGameplayTaskState::Finished: // If a task has finished, and it's being revived let's just treat the same as AwaitingActivation PerformActivation(); break; default: checkNoEntry(); // looks like unhandled value! Probably a new enum entry has been added break; } }
void UNavigationComponent::NotifyPathUpdate() { UE_VLOG(GetOwner(), LogNavigation, Log, TEXT("NotifyPathUpdate points:%d valid:%s"), Path.IsValid() ? Path->PathPoints.Num() : 0, Path.IsValid() ? (Path->IsValid() ? TEXT("yes") : TEXT("no")) : TEXT("missing!")); if (MyPathObserver != NULL) { MyPathObserver->OnPathUpdated(this); } if (PathFollowComp && bNotifyPathFollowing) { PathFollowComp->UpdateMove(Path); } if (!Path.IsValid() || !Path->IsValid()) { // If pointer is valid, nav-path is not. Print information so we'll know exactly what went wrong when we hit the check below. UE_CVLOG(Path.IsValid(), GetOwner(), LogNavigation, Warning, TEXT("NotifyPathUpdate fetched invalid NavPath! NavPath has %d points, is%sready, and is%sup-to-date"), Path->PathPoints.Num(), Path->IsReady() ? TEXT(" ") : TEXT(" NOT "), Path->IsUpToDate() ? TEXT(" ") : TEXT(" NOT ") ); ResetTransientData(); } }
void FEQSSceneProxy::CollectEQSData(const UPrimitiveComponent* InComponent, const IEQSQueryResultSourceInterface* InQueryDataSource, TArray<FSphere>& Spheres, TArray<FText3d>& Texts, TArray<EQSDebug::FDebugHelper>& DebugItems) { AActor* ActorOwner = InComponent ? InComponent->GetOwner() : NULL; IEQSQueryResultSourceInterface* QueryDataSource = const_cast<IEQSQueryResultSourceInterface*>(InQueryDataSource); if (QueryDataSource == NULL) { QueryDataSource = Cast<IEQSQueryResultSourceInterface>(ActorOwner); if (QueryDataSource == NULL) { QueryDataSource = Cast<IEQSQueryResultSourceInterface>(const_cast<UPrimitiveComponent*>(InComponent)); if (QueryDataSource == NULL) { return; } } } const FEnvQueryResult* ResultItems = QueryDataSource->GetQueryResult(); const FEnvQueryInstance* QueryInstance = QueryDataSource->GetQueryInstance(); FEQSSceneProxy::CollectEQSData(ResultItems, QueryInstance, QueryDataSource->GetHighlightRangePct(), QueryDataSource->GetShouldDrawFailedItems(), Spheres, Texts, DebugItems); if (ActorOwner && Spheres.Num() > EQSMaxItemsDrawn) { UE_VLOG(ActorOwner, LogEQS, Warning, TEXT("EQS drawing: too much items to draw! Drawing first %d from set of %d") , EQSMaxItemsDrawn , Spheres.Num() ); } }
FAIRequestID AAIController::RequestPathAndMove(const FAIMoveRequest& MoveRequest, FPathFindingQuery& Query) { FAIRequestID RequestID; UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(GetWorld()); if (NavSys) { FPathFindingResult PathResult = NavSys->FindPathSync(Query); if (PathResult.Result != ENavigationQueryResult::Error) { if (PathResult.IsSuccessful() && PathResult.Path.IsValid()) { if (MoveRequest.IsUsingPathfinding()) { if (MoveRequest.HasGoalActor()) { PathResult.Path->SetGoalActorObservation(*MoveRequest.GetGoalActor(), 100.0f); } PathResult.Path->EnableRecalculationOnInvalidation(true); } RequestID = RequestMove(MoveRequest, PathResult.Path); } } else { UE_VLOG(this, LogAINavigation, Error, TEXT("Trying to find path to %s resulted in Error"), *GetNameSafe(MoveRequest.GetGoalActor())); } } return RequestID; }