2022-05-02 09:15:14 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "Components/StateTreeComponentSchema.h"
2024-02-28 09:45:27 -05:00
# include "AIController.h"
# include "BrainComponent.h"
# include "Engine/World.h"
# include "GameFramework/Pawn.h"
2022-05-02 09:15:14 -04:00
# include "StateTreeConditionBase.h"
2024-05-15 14:50:35 -04:00
# include "StateTreeConsiderationBase.h"
2022-05-02 09:15:14 -04:00
# include "StateTreeEvaluatorBase.h"
2024-02-28 09:45:27 -05:00
# include "StateTreeExecutionContext.h"
2022-05-02 09:15:14 -04:00
# include "StateTreeTaskBase.h"
# include "Subsystems/WorldSubsystem.h"
2024-03-01 07:42:54 -05:00
# include "Tasks/StateTreeAITask.h"
2024-02-28 09:45:27 -05:00
# include "VisualLogger/VisualLogger.h"
2024-06-04 03:56:38 -04:00
# include "StateTreePropertyFunctionBase.h"
2022-08-29 14:47:43 -04:00
UStateTreeComponentSchema : : UStateTreeComponentSchema ( )
: ContextActorClass ( AActor : : StaticClass ( ) )
2024-03-01 07:42:54 -05:00
, ContextDataDescs ( { { FName ( " Actor " ) , AActor : : StaticClass ( ) , FGuid ( 0x1D971B00 , 0x28884FDE , 0xB5436802 , 0x36984FD5 ) } } )
2022-08-29 14:47:43 -04:00
{
}
2022-05-02 09:15:14 -04:00
bool UStateTreeComponentSchema : : IsStructAllowed ( const UScriptStruct * InScriptStruct ) const
{
return InScriptStruct - > IsChildOf ( FStateTreeConditionCommonBase : : StaticStruct ( ) )
| | InScriptStruct - > IsChildOf ( FStateTreeEvaluatorCommonBase : : StaticStruct ( ) )
2024-05-15 14:50:35 -04:00
| | InScriptStruct - > IsChildOf ( FStateTreeTaskCommonBase : : StaticStruct ( ) )
2024-06-04 03:56:38 -04:00
| | InScriptStruct - > IsChildOf ( FStateTreeConsiderationCommonBase : : StaticStruct ( ) )
| | InScriptStruct - > IsChildOf ( FStateTreePropertyFunctionCommonBase : : StaticStruct ( ) ) ;
2022-05-02 09:15:14 -04:00
}
bool UStateTreeComponentSchema : : IsClassAllowed ( const UClass * InClass ) const
{
return IsChildOfBlueprintBase ( InClass ) ;
}
bool UStateTreeComponentSchema : : IsExternalItemAllowed ( const UStruct & InStruct ) const
{
return InStruct . IsChildOf ( AActor : : StaticClass ( ) )
| | InStruct . IsChildOf ( UActorComponent : : StaticClass ( ) )
| | InStruct . IsChildOf ( UWorldSubsystem : : StaticClass ( ) ) ;
}
2022-08-29 14:47:43 -04:00
2022-09-19 19:47:11 -04:00
TConstArrayView < FStateTreeExternalDataDesc > UStateTreeComponentSchema : : GetContextDataDescs ( ) const
2022-08-29 14:47:43 -04:00
{
2024-03-01 07:42:54 -05:00
return ContextDataDescs ;
2022-08-29 14:47:43 -04:00
}
2022-09-05 09:08:59 -04:00
void UStateTreeComponentSchema : : PostLoad ( )
{
Super : : PostLoad ( ) ;
2024-03-01 07:42:54 -05:00
GetContextActorDataDesc ( ) . Struct = ContextActorClass . Get ( ) ;
2022-09-05 09:08:59 -04:00
}
2022-08-29 14:48:32 -04:00
# if WITH_EDITOR
2022-08-29 14:47:43 -04:00
void UStateTreeComponentSchema : : PostEditChangeChainProperty ( FPropertyChangedChainEvent & PropertyChangedEvent )
{
Super : : PostEditChangeChainProperty ( PropertyChangedEvent ) ;
FProperty * Property = PropertyChangedEvent . Property ;
if ( Property )
{
if ( Property - > GetOwnerClass ( ) = = UStateTreeComponentSchema : : StaticClass ( )
& & Property - > GetFName ( ) = = GET_MEMBER_NAME_CHECKED ( UStateTreeComponentSchema , ContextActorClass ) )
{
2024-03-01 07:42:54 -05:00
GetContextActorDataDesc ( ) . Struct = ContextActorClass . Get ( ) ;
2022-08-29 14:47:43 -04:00
}
}
}
2023-01-16 17:04:48 -05:00
# endif
2024-02-28 09:45:27 -05:00
bool UStateTreeComponentSchema : : SetContextRequirements ( UBrainComponent & BrainComponent , FStateTreeExecutionContext & Context , bool bLogErrors /*= false*/ )
{
if ( ! Context . IsValid ( ) )
{
return false ;
}
// Make sure the actor matches one required.
AActor * ContextActor = nullptr ;
const UStateTreeComponentSchema * Schema = Cast < UStateTreeComponentSchema > ( Context . GetStateTree ( ) - > GetSchema ( ) ) ;
if ( Schema )
{
AAIController * AIOwner = BrainComponent . GetAIOwner ( ) ;
if ( AAIController * OwnerController = ( AIOwner ! = nullptr ) ? AIOwner : Cast < AAIController > ( BrainComponent . GetOwner ( ) ) )
{
if ( OwnerController & & OwnerController - > IsA ( Schema - > GetContextActorClass ( ) ) )
{
ContextActor = OwnerController ;
}
}
if ( ContextActor = = nullptr )
{
if ( AActor * OwnerActor = ( AIOwner ! = nullptr ) ? AIOwner - > GetPawn ( ) : BrainComponent . GetOwner ( ) )
{
if ( OwnerActor & & OwnerActor - > IsA ( Schema - > GetContextActorClass ( ) ) )
{
ContextActor = OwnerActor ;
}
}
}
if ( ContextActor = = nullptr & & bLogErrors )
{
UE_VLOG ( BrainComponent . GetOwner ( ) , LogStateTree , Error , TEXT ( " %s: Could not find context actor of type %s. StateTree will not update. " ) , ANSI_TO_TCHAR ( __FUNCTION__ ) , * GetNameSafe ( Schema - > GetContextActorClass ( ) ) ) ;
}
}
else if ( bLogErrors )
{
UE_VLOG ( BrainComponent . GetOwner ( ) , LogStateTree , Error , TEXT ( " %s: Expected StateTree asset to contain StateTreeComponentSchema. StateTree will not update. " ) , ANSI_TO_TCHAR ( __FUNCTION__ ) ) ;
}
const FName ActorName ( TEXT ( " Actor " ) ) ;
Context . SetContextDataByName ( ActorName , FStateTreeDataView ( ContextActor ) ) ;
bool bResult = Context . AreContextDataViewsValid ( ) ;
if ( ! bResult & & bLogErrors )
{
UE_VLOG ( BrainComponent . GetOwner ( ) , LogStateTree , Error , TEXT ( " %s: Missing external data requirements. StateTree will not update. " ) , ANSI_TO_TCHAR ( __FUNCTION__ ) ) ;
}
return bResult ;
}
bool UStateTreeComponentSchema : : CollectExternalData ( const FStateTreeExecutionContext & Context , const UStateTree * StateTree , TArrayView < const FStateTreeExternalDataDesc > ExternalDataDescs , TArrayView < FStateTreeDataView > OutDataViews )
{
const UWorld * World = Context . GetWorld ( ) ;
if ( World = = nullptr )
{
return false ;
}
check ( ExternalDataDescs . Num ( ) = = OutDataViews . Num ( ) ) ;
AActor * Owner = Cast < AActor > ( Context . GetOwner ( ) ) ;
if ( ! Owner )
{
return false ;
}
AAIController * AIOwner = Cast < AAIController > ( Owner ) ;
for ( int32 Index = 0 ; Index < ExternalDataDescs . Num ( ) ; Index + + )
{
const FStateTreeExternalDataDesc & ItemDesc = ExternalDataDescs [ Index ] ;
if ( ItemDesc . Struct ! = nullptr )
{
if ( ItemDesc . Struct - > IsChildOf ( UWorldSubsystem : : StaticClass ( ) ) )
{
UWorldSubsystem * Subsystem = World - > GetSubsystemBase ( Cast < UClass > ( const_cast < UStruct * > ( ItemDesc . Struct . Get ( ) ) ) ) ;
OutDataViews [ Index ] = FStateTreeDataView ( Subsystem ) ;
}
else if ( ItemDesc . Struct - > IsChildOf ( UActorComponent : : StaticClass ( ) ) )
{
UActorComponent * Component = Owner - > FindComponentByClass ( Cast < UClass > ( const_cast < UStruct * > ( ItemDesc . Struct . Get ( ) ) ) ) ;
OutDataViews [ Index ] = FStateTreeDataView ( Component ) ;
}
else if ( ItemDesc . Struct - > IsChildOf ( APawn : : StaticClass ( ) ) )
{
APawn * OwnerPawn = ( AIOwner ! = nullptr ) ? AIOwner - > GetPawn ( ) : Cast < APawn > ( Owner ) ;
OutDataViews [ Index ] = FStateTreeDataView ( OwnerPawn ) ;
}
else if ( ItemDesc . Struct - > IsChildOf ( AAIController : : StaticClass ( ) ) )
{
AAIController * OwnerController = AIOwner ;
OutDataViews [ Index ] = FStateTreeDataView ( OwnerController ) ;
}
else if ( ItemDesc . Struct - > IsChildOf ( AActor : : StaticClass ( ) ) )
{
AActor * OwnerActor = ( AIOwner ! = nullptr ) ? AIOwner - > GetPawn ( ) : Owner ;
OutDataViews [ Index ] = FStateTreeDataView ( OwnerActor ) ;
}
}
}
return true ;
}