You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Moved SmartObjects out of restricted folder Moved StateTree out of restricted folder Moved ZoneGraph out of restricted folder Moved ZoneGraphAnnotations out of restricted folder #jira UE-115297 #ROBOMERGE-OWNER: mieszko.zielinski #ROBOMERGE-AUTHOR: mieszko.zielinski #ROBOMERGE-SOURCE: CL 17648223 via CL 17648246 via CL 17648261 via CL 17648385 via CL 17648390 via CL 17648742 #ROBOMERGE-BOT: STARSHIP (Release-Engine-Test -> Main) (v875-17642767) [CL 17648750 by mieszko zielinski in ue5-main branch]
275 lines
7.7 KiB
C++
275 lines
7.7 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "StateTreeState.h"
|
|
#include "StateTreeEditorData.h"
|
|
#include "StateTree.h"
|
|
#include "StateTreeConditionBase.h"
|
|
#include "StateTreeDelegates.h"
|
|
#include "CoreMinimal.h"
|
|
#include "UObject/Field.h"
|
|
|
|
void FStateTreeStateLink::Set(const EStateTreeTransitionType InType, const UStateTreeState* InState)
|
|
{
|
|
Type = InType;
|
|
if (Type == EStateTreeTransitionType::GotoState)
|
|
{
|
|
check(InState);
|
|
Name = InState->Name;
|
|
ID = InState->ID;
|
|
}
|
|
}
|
|
|
|
|
|
FStateTreeTransition2::FStateTreeTransition2(const EStateTreeTransitionEvent InEvent, const EStateTreeTransitionType InType, const UStateTreeState* InState)
|
|
{
|
|
Event = InEvent;
|
|
State.Set(InType, InState);
|
|
}
|
|
|
|
|
|
UStateTreeState::UStateTreeState(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
, ID(FGuid::NewGuid())
|
|
, Parent(nullptr)
|
|
{
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
void UStateTreeState::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent)
|
|
{
|
|
Super::PostEditChangeChainProperty(PropertyChangedEvent);
|
|
|
|
FProperty* Property = PropertyChangedEvent.Property;
|
|
FProperty* MemberProperty = nullptr;
|
|
if (PropertyChangedEvent.PropertyChain.GetActiveMemberNode())
|
|
{
|
|
MemberProperty = PropertyChangedEvent.PropertyChain.GetActiveMemberNode()->GetValue();
|
|
}
|
|
|
|
if (Property)
|
|
{
|
|
if (Property->GetOwnerClass() == UStateTreeState::StaticClass() &&
|
|
Property->GetFName() == GET_MEMBER_NAME_CHECKED(UStateTreeState, Name))
|
|
{
|
|
UStateTree* StateTree = GetTypedOuter<UStateTree>();
|
|
if (ensure(StateTree))
|
|
{
|
|
UE::StateTree::Delegates::OnIdentifierChanged.Broadcast(*StateTree);
|
|
}
|
|
}
|
|
|
|
if (PropertyChangedEvent.ChangeType == EPropertyChangeType::Duplicate && MemberProperty)
|
|
{
|
|
// Ensure unique ID on duplicated items.
|
|
if (MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UStateTreeState, Evaluators))
|
|
{
|
|
const int32 ArrayIndex = PropertyChangedEvent.GetArrayIndex(MemberProperty->GetFName().ToString());
|
|
if (Evaluators.IsValidIndex(ArrayIndex))
|
|
{
|
|
if (UStateTreeEvaluatorBase* Eval = Evaluators[ArrayIndex])
|
|
{
|
|
Eval->SetNewUniqueID();
|
|
Eval->SetName(FName(Eval->GetName().ToString() + TEXT(" Duplicate")));
|
|
}
|
|
}
|
|
}
|
|
if (MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UStateTreeState, Tasks))
|
|
{
|
|
const int32 ArrayIndex = PropertyChangedEvent.GetArrayIndex(MemberProperty->GetFName().ToString());
|
|
if (Tasks.IsValidIndex(ArrayIndex))
|
|
{
|
|
if (UStateTreeTaskBase* Task = Tasks[ArrayIndex])
|
|
{
|
|
Task->SetNewUniqueID();
|
|
Task->Name = FName(Task->Name.ToString() + TEXT(" Duplicate"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (IsV2())
|
|
{
|
|
if (MemberProperty)
|
|
{
|
|
// Ensure unique ID on duplicated items.
|
|
if (PropertyChangedEvent.ChangeType == EPropertyChangeType::Duplicate)
|
|
{
|
|
if (MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UStateTreeState, Evaluators2))
|
|
{
|
|
const int32 ArrayIndex = PropertyChangedEvent.GetArrayIndex(MemberProperty->GetFName().ToString());
|
|
if (Evaluators2.IsValidIndex(ArrayIndex))
|
|
{
|
|
if (FStateTreeEvaluator2Base* Eval = Evaluators2[ArrayIndex].Type.GetMutablePtr<FStateTreeEvaluator2Base>())
|
|
{
|
|
Eval->ID = FGuid::NewGuid();
|
|
Eval->Name = FName(Eval->Name.ToString() + TEXT(" Duplicate"));
|
|
}
|
|
}
|
|
}
|
|
if (MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UStateTreeState, Tasks2))
|
|
{
|
|
const int32 ArrayIndex = PropertyChangedEvent.GetArrayIndex(MemberProperty->GetFName().ToString());
|
|
if (Tasks2.IsValidIndex(ArrayIndex))
|
|
{
|
|
if (FStateTreeTask2Base* Task = Tasks2[ArrayIndex].Type.GetMutablePtr<FStateTreeTask2Base>())
|
|
{
|
|
Task->ID = FGuid::NewGuid();
|
|
Task->Name = FName(Task->Name.ToString() + TEXT(" Duplicate"));
|
|
}
|
|
}
|
|
}
|
|
if (MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(UStateTreeState, EnterConditions2))
|
|
{
|
|
const int32 ArrayIndex = PropertyChangedEvent.GetArrayIndex(MemberProperty->GetFName().ToString());
|
|
if (Tasks2.IsValidIndex(ArrayIndex))
|
|
{
|
|
if (FStateTreeConditionBase* Cond = EnterConditions2[ArrayIndex].Type.GetMutablePtr<FStateTreeConditionBase>())
|
|
{
|
|
Cond->ID = FGuid::NewGuid();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UStateTreeState::PostLoad()
|
|
{
|
|
Super::PostLoad();
|
|
|
|
UStateTree* StateTree = GetTypedOuter<UStateTree>();
|
|
if (StateTree->IsV2())
|
|
{
|
|
// Convert existing default transitions.
|
|
Modify();
|
|
|
|
if (StateFailedTransition.Type != EStateTreeTransitionType::NotSet
|
|
&& StateFailedTransition.Type != EStateTreeTransitionType::SelectChildState)
|
|
{
|
|
if (StateFailedTransition.IsValid())
|
|
{
|
|
FStateTreeTransition2& Transition = Transitions2.AddDefaulted_GetRef();
|
|
Transition.Event = EStateTreeTransitionEvent::OnFailed;
|
|
Transition.State = StateFailedTransition;
|
|
}
|
|
// Reset
|
|
StateFailedTransition = FStateTreeStateLink(EStateTreeTransitionType::NotSet);
|
|
}
|
|
|
|
if (StateDoneTransition.Type != EStateTreeTransitionType::NotSet
|
|
&& StateDoneTransition.Type != EStateTreeTransitionType::SelectChildState) // Select child state is inferred automatically in V2
|
|
{
|
|
if (StateDoneTransition.IsValid())
|
|
{
|
|
FStateTreeTransition2& Transition = Transitions2.AddDefaulted_GetRef();
|
|
Transition.Event = EStateTreeTransitionEvent::OnCompleted;
|
|
Transition.State = StateDoneTransition;
|
|
}
|
|
// Reset
|
|
StateDoneTransition = FStateTreeStateLink(EStateTreeTransitionType::NotSet);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
void UStateTreeState::GetVisibleVariables(FStateTreeVariableLayout& Variables) const
|
|
{
|
|
// Add input parameters
|
|
UStateTree* StateTree = GetTypedOuter<UStateTree>();
|
|
if (ensure(StateTree))
|
|
{
|
|
const FStateTreeVariableLayout& ParameterLayout = StateTree->GetInputParameterLayout();
|
|
for (const FStateTreeVariableDesc& Var : ParameterLayout.Variables)
|
|
{
|
|
Variables.DefineVariable(Var);
|
|
}
|
|
}
|
|
|
|
// Collect states variable descs up to the highest parent
|
|
for (const UStateTreeState* State = this; State; State = State->Parent)
|
|
{
|
|
for (const UStateTreeEvaluatorBase* Evaluator : State->Evaluators)
|
|
{
|
|
if (Evaluator)
|
|
{
|
|
Evaluator->DefineOutputVariables(Variables);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const UStateTreeTaskBase* UStateTreeState::GetTaskByID(FGuid InID) const
|
|
{
|
|
const int32 Index = Tasks.IndexOfByPredicate([InID](const UStateTreeTaskBase* Task) -> bool { return Task->ID == InID; });
|
|
return Index != INDEX_NONE ? Tasks[Index] : nullptr;
|
|
}
|
|
|
|
UStateTreeTaskBase* UStateTreeState::GetTaskByID(FGuid InID)
|
|
{
|
|
const int32 Index = Tasks.IndexOfByPredicate([InID](const UStateTreeTaskBase* Task) -> bool { return Task->ID == InID; });
|
|
return Index != INDEX_NONE ? Tasks[Index] : nullptr;
|
|
}
|
|
|
|
const FStateTreeTask2Base* UStateTreeState::GetTask2ByID(FGuid InID) const
|
|
{
|
|
for (const FStateTreeTaskItem& TaskItem : Tasks2)
|
|
{
|
|
if (const FStateTreeTask2Base* Task = TaskItem.Type.GetPtr<FStateTreeTask2Base>())
|
|
{
|
|
if (Task->ID == InID)
|
|
{
|
|
return Task;
|
|
}
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
FStateTreeTask2Base* UStateTreeState::GetTask2ByID(FGuid InID)
|
|
{
|
|
for (FStateTreeTaskItem& TaskItem : Tasks2)
|
|
{
|
|
if (FStateTreeTask2Base* Task = TaskItem.Type.GetMutablePtr<FStateTreeTask2Base>())
|
|
{
|
|
if (Task->ID == InID)
|
|
{
|
|
return Task;
|
|
}
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
UStateTreeState* UStateTreeState::GetNextSiblingState() const
|
|
{
|
|
if (!Parent)
|
|
{
|
|
return nullptr;
|
|
}
|
|
for (int32 ChildIdx = 0; ChildIdx < Parent->Children.Num(); ChildIdx++)
|
|
{
|
|
if (Parent->Children[ChildIdx] == this)
|
|
{
|
|
const int NextIdx = ChildIdx + 1;
|
|
if (NextIdx < Parent->Children.Num())
|
|
{
|
|
return Parent->Children[NextIdx];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool UStateTreeState::IsV2() const
|
|
{
|
|
if (const UStateTree* StateTree = GetTypedOuter<UStateTree>())
|
|
{
|
|
return StateTree->IsV2();
|
|
}
|
|
return false;
|
|
} |