void UGameplayTasksComponent::OnGameplayTaskActivated(UGameplayTask& Task) { // process events after finishing all operations FEventLock ScopeEventLock(this); if (Task.IsTickingTask()) { check(TickingTasks.Contains(&Task) == false); TickingTasks.Add(&Task); // If this is our first ticking task, set this component as active so it begins ticking if (TickingTasks.Num() == 1) { UpdateShouldTick(); } } if (Task.IsSimulatedTask()) { check(SimulatedTasks.Contains(&Task) == false); SimulatedTasks.Add(&Task); } IGameplayTaskOwnerInterface* TaskOwner = Task.GetTaskOwner(); if (!Task.IsOwnedByTasksComponent() && TaskOwner) { TaskOwner->OnGameplayTaskActivated(Task); } }
static FString DescribeTaskHelper(const UGameplayTask& TaskOb) { const UObject* OwnerOb = Cast<const UObject>(TaskOb.GetTaskOwner()); return FString::Printf(TEXT("\n {white}%s%s {%s}%s:%d {white}Owner:{yellow}%s {white}Res:{yellow}%s"), *TaskOb.GetName(), TaskOb.GetInstanceName() != NAME_None ? *FString::Printf(TEXT(" {yellow}[%s]"), *TaskOb.GetInstanceName().ToString()) : TEXT(""), TaskOb.IsActive() ? TEXT("green") : TEXT("orange"), *TaskOb.GetTaskStateName(), TaskOb.GetPriority(), *GetNameSafe(OwnerOb), TaskOb.GetRequiredResources().IsEmpty() ? TEXT("None") : *TaskOb.GetRequiredResources().GetDebugDescription()); }
//----------------------------------------------------------------------// // UBTTaskNode IGameplayTaskOwnerInterface //----------------------------------------------------------------------// void UBTTaskNode::OnTaskDeactivated(UGameplayTask& Task) { ensure(Task.GetTaskOwner() == this); UBehaviorTreeComponent* BTComp = GetBTComponentForTask(Task); if (BTComp) { // this is a super-default behavior. Specific task will surely like to // handle this themselves, finishing with specific result const EBTTaskStatus::Type Status = BTComp->GetTaskStatus(this); FinishLatentTask(*BTComp, Status == EBTTaskStatus::Aborting ? EBTNodeResult::Aborted : EBTNodeResult::Succeeded); } }
void UGameplayTasksComponent::OnGameplayTaskDeactivated(UGameplayTask& Task) { // process events after finishing all operations FEventLock ScopeEventLock(this); const bool bIsFinished = (Task.GetState() == EGameplayTaskState::Finished); if (Task.GetChildTask() && bIsFinished) { if (Task.HasOwnerFinished()) { Task.GetChildTask()->TaskOwnerEnded(); } else { Task.GetChildTask()->EndTask(); } } if (Task.IsTickingTask()) { // If we are removing our last ticking task, set this component as inactive so it stops ticking TickingTasks.RemoveSingleSwap(&Task); } if (Task.IsSimulatedTask()) { SimulatedTasks.RemoveSingleSwap(&Task); } // Resource-using task if (Task.RequiresPriorityOrResourceManagement() && bIsFinished) { OnTaskEnded(Task); } IGameplayTaskOwnerInterface* TaskOwner = Task.GetTaskOwner(); if (!Task.IsOwnedByTasksComponent() && !Task.HasOwnerFinished() && TaskOwner) { TaskOwner->OnGameplayTaskDeactivated(Task); } UpdateShouldTick(); }
EGameplayTaskRunResult UGameplayTasksComponent::RunGameplayTask(IGameplayTaskOwnerInterface& TaskOwner, UGameplayTask& Task, uint8 Priority, FGameplayResourceSet AdditionalRequiredResources, FGameplayResourceSet AdditionalClaimedResources) { const FText NoneText = FText::FromString(TEXT("None")); if (Task.GetState() == EGameplayTaskState::Paused || Task.GetState() == EGameplayTaskState::Active) { // return as success if already running for the same owner, failure otherwise return Task.GetTaskOwner() == &TaskOwner ? (Task.GetState() == EGameplayTaskState::Paused ? EGameplayTaskRunResult::Success_Paused : EGameplayTaskRunResult::Success_Active) : EGameplayTaskRunResult::Error; } // this is a valid situation if the task has been created via "Construct Object" mechanics if (Task.GetState() == EGameplayTaskState::Uninitialized) { Task.InitTask(TaskOwner, Priority); } Task.AddRequiredResourceSet(AdditionalRequiredResources); Task.AddClaimedResourceSet(AdditionalClaimedResources); Task.ReadyForActivation(); switch (Task.GetState()) { case EGameplayTaskState::AwaitingActivation: case EGameplayTaskState::Paused: return EGameplayTaskRunResult::Success_Paused; break; case EGameplayTaskState::Active: return EGameplayTaskRunResult::Success_Active; break; case EGameplayTaskState::Finished: return EGameplayTaskRunResult::Success_Active; break; } return EGameplayTaskRunResult::Error; }