2022-05-06 08:23:48 -04:00
|
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
|
|
#include "ContextualAnimStateTreeTask.h"
|
2022-06-21 12:21:16 -04:00
|
|
|
|
|
2022-05-06 08:23:48 -04:00
|
|
|
|
#include "ContextualAnimSceneAsset.h"
|
|
|
|
|
|
#include "StateTreeExecutionContext.h"
|
|
|
|
|
|
#include "StateTreeLinker.h"
|
2022-06-21 12:21:16 -04:00
|
|
|
|
#include "GameplayTask_PlayContextualAnim.h"
|
|
|
|
|
|
#include "VisualLogger/VisualLogger.h"
|
2022-05-06 08:23:48 -04:00
|
|
|
|
|
2022-09-28 01:06:15 -04:00
|
|
|
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(ContextualAnimStateTreeTask)
|
|
|
|
|
|
|
2022-05-06 08:23:48 -04:00
|
|
|
|
|
2022-06-21 12:21:16 -04:00
|
|
|
|
#define ST_ANIM_TASK_LOG(Verbosity, Format, ...) UE_VLOG_UELOG(Context.GetOwner(), LogStateTree, Verbosity, TEXT("[%s] ") Format, *StaticStruct()->GetName(), ##__VA_ARGS__)
|
|
|
|
|
|
#define ST_ANIM_TASK_CLOG(Condition, Verbosity, Format, ...) UE_CVLOG_UELOG((Condition), Context.GetOwner(), LogStateTree, Verbosity, TEXT("[%s] ") Format, *StaticStruct()->GetName(), ##__VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* FContextualAnimStateTreeTask
|
|
|
|
|
|
*/
|
2022-09-28 09:55:53 -04:00
|
|
|
|
EStateTreeRunStatus FContextualAnimStateTreeTask::EnterState(FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) const
|
2022-05-06 08:23:48 -04:00
|
|
|
|
{
|
2022-06-21 12:21:16 -04:00
|
|
|
|
if (!bEnabled)
|
|
|
|
|
|
{
|
|
|
|
|
|
return EStateTreeRunStatus::Succeeded;
|
|
|
|
|
|
}
|
2022-05-06 08:23:48 -04:00
|
|
|
|
|
2022-09-29 20:26:53 -04:00
|
|
|
|
FInstanceDataType& InstanceData = Context.GetInstanceData(*this);
|
2022-09-19 19:47:11 -04:00
|
|
|
|
|
2022-06-29 17:09:59 -04:00
|
|
|
|
const UContextualAnimSceneAsset* SceneAsset = InstanceData.ContextualAnimAsset;
|
2022-06-21 12:21:16 -04:00
|
|
|
|
if (SceneAsset == nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
ST_ANIM_TASK_LOG(Error, TEXT("ContextualAnimSceneAsset required."));
|
|
|
|
|
|
return EStateTreeRunStatus::Failed;
|
|
|
|
|
|
}
|
2022-09-19 19:47:11 -04:00
|
|
|
|
AActor* Interactor = InstanceData.Actor;
|
2022-06-29 17:09:59 -04:00
|
|
|
|
AActor* InteractableObject = InstanceData.InteractableObject;
|
2022-06-21 12:21:16 -04:00
|
|
|
|
if (InteractableObject == nullptr)
|
2022-05-06 08:23:48 -04:00
|
|
|
|
{
|
2022-06-21 12:21:16 -04:00
|
|
|
|
ST_ANIM_TASK_LOG(Error, TEXT("Interactable object actor required."));
|
|
|
|
|
|
return EStateTreeRunStatus::Failed;
|
2022-05-06 08:23:48 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-06-21 12:21:16 -04:00
|
|
|
|
// Create task which will also be simulated on the clients
|
2022-09-02 21:52:41 -04:00
|
|
|
|
TObjectPtr<UGameplayTask_PlayContextualAnim>& Task = InstanceData.Task;
|
2022-06-21 12:21:16 -04:00
|
|
|
|
|
|
|
|
|
|
Task = UGameplayTask_PlayContextualAnim::PlayContextualAnim(
|
2022-09-19 19:47:11 -04:00
|
|
|
|
Interactor,
|
2022-06-29 17:09:59 -04:00
|
|
|
|
InstanceData.InteractorRole,
|
2022-06-21 12:21:16 -04:00
|
|
|
|
InteractableObject,
|
2022-06-29 17:09:59 -04:00
|
|
|
|
InstanceData.InteractableObjectRole,
|
2022-06-21 12:21:16 -04:00
|
|
|
|
Section,
|
|
|
|
|
|
ExitSection,
|
|
|
|
|
|
SceneAsset
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (Task == nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
ST_ANIM_TASK_LOG(Error, TEXT("Unable to create gameplay task."));
|
|
|
|
|
|
return EStateTreeRunStatus::Failed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Task->ReadyForActivation();
|
2022-05-06 08:23:48 -04:00
|
|
|
|
|
|
|
|
|
|
return EStateTreeRunStatus::Running;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EStateTreeRunStatus FContextualAnimStateTreeTask::Tick(FStateTreeExecutionContext& Context, const float DeltaTime) const
|
|
|
|
|
|
{
|
2022-06-21 12:21:16 -04:00
|
|
|
|
EStateTreeRunStatus Status = EStateTreeRunStatus::Running;
|
2022-05-06 08:23:48 -04:00
|
|
|
|
|
2022-09-29 20:26:53 -04:00
|
|
|
|
FInstanceDataType& InstanceData = Context.GetInstanceData(*this);
|
2022-06-29 17:09:59 -04:00
|
|
|
|
const float Duration = InstanceData.Duration;
|
2022-06-21 12:21:16 -04:00
|
|
|
|
if (Duration > 0.f)
|
|
|
|
|
|
{
|
2022-06-29 17:09:59 -04:00
|
|
|
|
float& Time = InstanceData.Time;
|
2022-06-21 12:21:16 -04:00
|
|
|
|
Time += DeltaTime;
|
|
|
|
|
|
if (Time >= Duration)
|
|
|
|
|
|
{
|
|
|
|
|
|
Status = EStateTreeRunStatus::Succeeded;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2022-09-02 21:52:41 -04:00
|
|
|
|
TObjectPtr<UGameplayTask_PlayContextualAnim>& Task = InstanceData.Task;
|
2022-06-21 12:21:16 -04:00
|
|
|
|
if (Task == nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
return EStateTreeRunStatus::Running;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const EPlayContextualAnimStatus GameplayTaskStatus = Task->GetStatus();
|
|
|
|
|
|
ensureAlwaysMsgf(GameplayTaskStatus != EPlayContextualAnimStatus::Unset, TEXT("TaskStatus is expected to be set before ticking the task"));
|
|
|
|
|
|
if (GameplayTaskStatus != EPlayContextualAnimStatus::Playing)
|
|
|
|
|
|
{
|
|
|
|
|
|
Status = (GameplayTaskStatus == EPlayContextualAnimStatus::DonePlaying ? EStateTreeRunStatus::Succeeded : EStateTreeRunStatus::Failed);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-28 09:55:53 -04:00
|
|
|
|
void FContextualAnimStateTreeTask::ExitState(FStateTreeExecutionContext& Context, const FStateTreeTransitionResult& Transition) const
|
2022-06-21 12:21:16 -04:00
|
|
|
|
{
|
|
|
|
|
|
if (!bEnabled)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2022-06-29 17:09:59 -04:00
|
|
|
|
|
2022-09-29 20:26:53 -04:00
|
|
|
|
FInstanceDataType& InstanceData = Context.GetInstanceData(*this);
|
2022-09-02 21:52:41 -04:00
|
|
|
|
TObjectPtr<UGameplayTask_PlayContextualAnim>& Task = InstanceData.Task;
|
2022-06-21 12:21:16 -04:00
|
|
|
|
if (Task == nullptr)
|
|
|
|
|
|
{
|
|
|
|
|
|
ST_ANIM_TASK_LOG(Error, TEXT("Unable to access gameplay task."));
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Update exit parameters if we are handling an interruption
|
2022-06-29 17:09:59 -04:00
|
|
|
|
const FGameplayInteractionAbortContext& AbortContext = InstanceData.AbortContext;
|
2022-06-21 12:21:16 -04:00
|
|
|
|
if (AbortContext.Reason != EGameplayInteractionAbortReason::Unset)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (AbortContext.Reason)
|
|
|
|
|
|
{
|
|
|
|
|
|
case EGameplayInteractionAbortReason::ExternalAbort: Task->SetExit(EPlayContextualAnimExitMode::DefaultExit, ExitSection); break;
|
|
|
|
|
|
case EGameplayInteractionAbortReason::InternalAbort: Task->SetExit(EPlayContextualAnimExitMode::Teleport, NAME_None); break;
|
|
|
|
|
|
//case EGameplayInteractionAbortReason::SomeOtherValue: Task->SetExit(EPlayContextualAnimExitMode::FastExit, FastExitSection); break;
|
|
|
|
|
|
case EGameplayInteractionAbortReason::Unset:
|
|
|
|
|
|
// no need to update the default setup
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
ensureMsgf(false, TEXT("Unhandled abort reason: %s"), *UEnum::GetValueAsString(AbortContext.Reason));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-09-28 01:06:15 -04:00
|
|
|
|
|