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;
	}
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
		}
	}
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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();
                }
            }
        }
    }
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 11
0
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);
}
Ejemplo n.º 12
0
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"));
		}
	}
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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));
		}
	}
}
Ejemplo n.º 17
0
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);
	}
}
Ejemplo n.º 18
0
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();
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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); 
}
Ejemplo n.º 23
0
//@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);
}
Ejemplo n.º 24
0
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"));
	}
}
Ejemplo n.º 25
0
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);
	}
}
Ejemplo n.º 27
0
//----------------------------------------------------------------------//
// 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()
			);
	}
}
Ejemplo n.º 30
0
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;
}