2019-12-26 15:33:43 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-05-22 12:00:20 -04:00
2019-09-23 07:23:26 -04:00
# include "AnimGraphNode_LinkedAnimGraphBase.h"
2019-05-22 12:00:20 -04:00
# include "Widgets/Text/STextBlock.h"
# include "Widgets/Input/SCheckBox.h"
# include "EdGraphSchema_K2.h"
# include "Kismet2/CompilerResultsLog.h"
# include "Kismet2/BlueprintEditorUtils.h"
# include "PropertyHandle.h"
# include "DetailLayoutBuilder.h"
# include "DetailCategoryBuilder.h"
2019-09-23 07:23:26 -04:00
# include "Animation/AnimNode_LinkedInputPose.h"
2019-05-22 12:00:20 -04:00
# include "PropertyCustomizationHelpers.h"
# include "ScopedTransaction.h"
# include "AnimationGraphSchema.h"
# include "Widgets/Layout/SBox.h"
# include "UObject/CoreRedirects.h"
2019-09-23 07:23:26 -04:00
# include "Animation/AnimNode_LinkedAnimGraph.h"
2021-01-06 09:11:59 -04:00
# include "AnimGraphAttributes.h"
2021-01-25 08:43:19 -04:00
# include "IAnimBlueprintCopyTermDefaultsContext.h"
2021-04-22 04:57:09 -04:00
# include "AnimBlueprintExtension_LinkedAnimGraph.h"
2021-05-24 06:55:32 -04:00
# include "EdGraphSchema_K2_Actions.h"
2019-05-22 12:00:20 -04:00
2019-09-23 07:23:26 -04:00
# define LOCTEXT_NAMESPACE "LinkedAnimGraph"
2019-05-22 12:00:20 -04:00
2019-09-23 07:23:26 -04:00
namespace LinkedAnimGraphGraphNodeConstants
2019-05-22 12:00:20 -04:00
{
FLinearColor TitleColor ( 0.2f , 0.2f , 0.8f ) ;
}
2020-09-01 14:07:48 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : AllocatePoseLinks ( )
{
FAnimNode_LinkedAnimGraph & RuntimeNode = * GetLinkedAnimGraphNode ( ) ;
RuntimeNode . InputPoses . Empty ( ) ;
RuntimeNode . InputPoseNames . Empty ( ) ;
for ( UEdGraphPin * Pin : Pins )
{
if ( ! Pin - > bOrphanedPin )
{
if ( UAnimationGraphSchema : : IsPosePin ( Pin - > PinType ) )
{
if ( Pin - > Direction = = EGPD_Input )
{
RuntimeNode . InputPoses . AddDefaulted ( ) ;
RuntimeNode . InputPoseNames . Add ( Pin - > GetFName ( ) ) ;
}
}
}
}
}
2019-09-23 07:23:26 -04:00
FLinearColor UAnimGraphNode_LinkedAnimGraphBase : : GetNodeTitleColor ( ) const
2019-05-22 12:00:20 -04:00
{
2019-09-23 07:23:26 -04:00
return LinkedAnimGraphGraphNodeConstants : : TitleColor ;
2019-05-22 12:00:20 -04:00
}
2021-05-24 06:55:32 -04:00
FSlateIcon UAnimGraphNode_LinkedAnimGraphBase : : GetIconAndTint ( FLinearColor & OutColor ) const
{
return FSlateIcon ( " EditorStyle " , " ClassIcon.AnimBlueprint " ) ;
}
2019-09-23 07:23:26 -04:00
FText UAnimGraphNode_LinkedAnimGraphBase : : GetTooltipText ( ) const
2019-05-22 12:00:20 -04:00
{
2019-09-23 07:23:26 -04:00
return LOCTEXT ( " ToolTip " , " Runs a linked anim graph in another instance to process animation " ) ;
2019-05-22 12:00:20 -04:00
}
2021-05-24 06:55:32 -04:00
FText UAnimGraphNode_LinkedAnimGraphBase : : GetMenuCategory ( ) const
{
return LOCTEXT ( " LinkedAnimGraphCategory " , " Linked Anim Blueprints " ) ;
}
2019-09-23 07:23:26 -04:00
FText UAnimGraphNode_LinkedAnimGraphBase : : GetNodeTitle ( ENodeTitleType : : Type TitleType ) const
2019-05-22 12:00:20 -04:00
{
UClass * TargetClass = GetTargetClass ( ) ;
UAnimBlueprint * TargetAnimBlueprint = TargetClass ? CastChecked < UAnimBlueprint > ( TargetClass - > ClassGeneratedBy ) : nullptr ;
2021-05-24 06:55:32 -04:00
const FName TargetAnimBlueprintName = TargetAnimBlueprint ? TargetAnimBlueprint - > GetFName ( ) : NAME_None ;
2019-09-23 07:23:26 -04:00
const FAnimNode_LinkedAnimGraph & Node = * GetLinkedAnimGraphNode ( ) ;
2019-05-22 12:00:20 -04:00
FFormatNamedArguments Args ;
2021-05-24 06:55:32 -04:00
Args . Add ( TEXT ( " NodeType " ) , LOCTEXT ( " Title " , " Linked Anim Graph " ) ) ;
Args . Add ( TEXT ( " TargetClass " ) , FText : : FromName ( TargetAnimBlueprintName ) ) ;
2019-05-22 12:00:20 -04:00
if ( TitleType = = ENodeTitleType : : MenuTitle )
{
2021-05-24 06:55:32 -04:00
return LOCTEXT ( " Title " , " Linked Anim Graph " ) ;
2019-05-22 12:00:20 -04:00
}
2021-05-24 06:55:32 -04:00
else if ( TitleType = = ENodeTitleType : : ListView )
2019-05-22 12:00:20 -04:00
{
if ( Node . Tag ! = NAME_None )
{
Args . Add ( TEXT ( " Tag " ) , FText : : FromName ( Node . Tag ) ) ;
2021-05-24 06:55:32 -04:00
return FText : : Format ( LOCTEXT ( " TitleListFormatTagged " , " {TargetClass} ({Tag}) " ) , Args ) ;
}
else if ( TargetClass )
{
return FText : : Format ( LOCTEXT ( " TitleListFormat " , " {TargetClass} " ) , Args ) ;
2019-05-22 12:00:20 -04:00
}
else
{
2021-05-24 06:55:32 -04:00
return LOCTEXT ( " Title " , " Linked Anim Graph " ) ;
2019-05-22 12:00:20 -04:00
}
}
else
{
if ( Node . Tag ! = NAME_None )
{
Args . Add ( TEXT ( " Tag " ) , FText : : FromName ( Node . Tag ) ) ;
2021-05-24 06:55:32 -04:00
return FText : : Format ( LOCTEXT ( " TitleFormatTagged " , " {TargetClass} ({Tag}) \n {NodeType} " ) , Args ) ;
}
else if ( TargetClass )
{
return FText : : Format ( LOCTEXT ( " TitleFormat " , " {TargetClass} \n {NodeType} " ) , Args ) ;
2019-05-22 12:00:20 -04:00
}
else
{
2021-05-24 06:55:32 -04:00
return LOCTEXT ( " Title " , " Linked Anim Graph " ) ;
2019-05-22 12:00:20 -04:00
}
}
}
2019-09-23 07:23:26 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : ValidateAnimNodeDuringCompilation ( USkeleton * ForSkeleton , FCompilerResultsLog & MessageLog )
2019-05-22 12:00:20 -04:00
{
Super : : ValidateAnimNodeDuringCompilation ( ForSkeleton , MessageLog ) ;
UAnimBlueprint * AnimBP = CastChecked < UAnimBlueprint > ( GetBlueprint ( ) ) ;
UObject * OriginalNode = MessageLog . FindSourceObject ( this ) ;
if ( HasInstanceLoop ( ) )
{
2019-09-23 07:23:26 -04:00
MessageLog . Error ( TEXT ( " Detected loop in linked instance chain starting at @@ inside class @@ " ) , this , AnimBP - > GetAnimBlueprintGeneratedClass ( ) ) ;
2019-05-22 12:00:20 -04:00
}
2019-09-23 07:23:26 -04:00
// Check for cycles from other linked instance nodes
2019-05-22 12:00:20 -04:00
TArray < UEdGraph * > Graphs ;
AnimBP - > GetAllGraphs ( Graphs ) ;
2019-09-23 07:23:26 -04:00
const FAnimNode_LinkedAnimGraph & Node = * GetLinkedAnimGraphNode ( ) ;
2019-05-22 12:00:20 -04:00
// Check for duplicate tags in this anim blueprint
for ( UEdGraph * Graph : Graphs )
{
2019-09-23 07:23:26 -04:00
TArray < UAnimGraphNode_LinkedAnimGraphBase * > LinkedAnimGraphNodes ;
Graph - > GetNodesOfClass ( LinkedAnimGraphNodes ) ;
2019-05-22 12:00:20 -04:00
2019-09-23 07:23:26 -04:00
for ( UAnimGraphNode_LinkedAnimGraphBase * LinkedAnimGraphNode : LinkedAnimGraphNodes )
2019-05-22 12:00:20 -04:00
{
2019-09-23 07:23:26 -04:00
if ( LinkedAnimGraphNode = = OriginalNode )
2019-05-22 12:00:20 -04:00
{
continue ;
}
2019-09-23 07:23:26 -04:00
FAnimNode_LinkedAnimGraph & InnerNode = * LinkedAnimGraphNode - > GetLinkedAnimGraphNode ( ) ;
2019-05-22 12:00:20 -04:00
if ( InnerNode . Tag ! = NAME_None & & InnerNode . Tag = = Node . Tag )
{
2019-09-23 07:23:26 -04:00
MessageLog . Error ( * FText : : Format ( LOCTEXT ( " DuplicateTagErrorFormat " , " Node @@ and node @@ both have the same tag '{0}'. " ) , FText : : FromName ( Node . Tag ) ) . ToString ( ) , this , LinkedAnimGraphNode ) ;
2019-05-22 12:00:20 -04:00
}
}
}
// Check we don't try to spawn our own blueprint
if ( GetTargetClass ( ) = = AnimBP - > GetAnimBlueprintGeneratedClass ( ) )
{
2019-09-23 07:23:26 -04:00
MessageLog . Error ( TEXT ( " Linked instance node @@ targets instance class @@ which it is inside, this would cause a loop. " ) , this , AnimBP - > GetAnimBlueprintGeneratedClass ( ) ) ;
2019-05-22 12:00:20 -04:00
}
}
2019-09-23 07:23:26 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : ReallocatePinsDuringReconstruction ( TArray < UEdGraphPin * > & OldPins )
2019-05-22 12:00:20 -04:00
{
// Grab the SKELETON class here as when we are reconstructed during during BP compilation
// the full generated class is not yet present built.
UClass * TargetClass = GetTargetSkeletonClass ( ) ;
if ( ! TargetClass )
{
// Nothing to search for properties
return ;
}
IAnimClassInterface * AnimClassInterface = IAnimClassInterface : : GetFromClass ( TargetClass ) ;
2019-09-23 07:23:26 -04:00
const FAnimNode_LinkedAnimGraph & Node = * GetLinkedAnimGraphNode ( ) ;
2019-05-22 12:00:20 -04:00
// Add any pose pins
for ( const FAnimBlueprintFunction & AnimBlueprintFunction : AnimClassInterface - > GetAnimBlueprintFunctions ( ) )
{
if ( AnimBlueprintFunction . Name = = Node . GetDynamicLinkFunctionName ( ) )
{
for ( const FName & PoseName : AnimBlueprintFunction . InputPoseNames )
{
UEdGraphPin * NewPin = CreatePin ( EEdGraphPinDirection : : EGPD_Input , UAnimationGraphSchema : : MakeLocalSpacePosePin ( ) , PoseName ) ;
NewPin - > PinFriendlyName = FText : : FromName ( PoseName ) ;
CustomizePinData ( NewPin , PoseName , INDEX_NONE ) ;
}
break ;
}
}
// Call super to add properties
Super : : ReallocatePinsDuringReconstruction ( OldPins ) ;
}
2019-09-23 07:23:26 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : PostEditChangeProperty ( FPropertyChangedEvent & PropertyChangedEvent )
2019-05-22 12:00:20 -04:00
{
Super : : PostEditChangeProperty ( PropertyChangedEvent ) ;
bool bRequiresNodeReconstruct = false ;
2019-12-13 11:07:03 -05:00
FProperty * ChangedProperty = PropertyChangedEvent . Property ;
2019-05-22 12:00:20 -04:00
if ( ChangedProperty )
{
if ( IsStructuralProperty ( ChangedProperty ) )
{
bRequiresNodeReconstruct = true ;
RebuildExposedProperties ( ) ;
}
}
if ( bRequiresNodeReconstruct )
{
ReconstructNode ( ) ;
}
}
2019-09-23 07:23:26 -04:00
bool UAnimGraphNode_LinkedAnimGraphBase : : HasInstanceLoop ( )
2019-05-22 12:00:20 -04:00
{
TArray < FGuid > VisitedList ;
TArray < FGuid > CurrentStack ;
return HasInstanceLoop_Recursive ( this , VisitedList , CurrentStack ) ;
}
2019-09-23 07:23:26 -04:00
bool UAnimGraphNode_LinkedAnimGraphBase : : HasInstanceLoop_Recursive ( UAnimGraphNode_LinkedAnimGraphBase * CurrNode , TArray < FGuid > & VisitedNodes , TArray < FGuid > & NodeStack )
2019-05-22 12:00:20 -04:00
{
if ( ! VisitedNodes . Contains ( CurrNode - > NodeGuid ) )
{
VisitedNodes . Add ( CurrNode - > NodeGuid ) ;
NodeStack . Add ( CurrNode - > NodeGuid ) ;
if ( UAnimBlueprint * AnimBP = Cast < UAnimBlueprint > ( UBlueprint : : GetBlueprintFromClass ( CurrNode - > GetTargetClass ( ) ) ) )
{
2019-09-23 07:23:26 -04:00
// Check for cycles from other linked instance nodes
2019-05-22 12:00:20 -04:00
TArray < UEdGraph * > Graphs ;
AnimBP - > GetAllGraphs ( Graphs ) ;
for ( UEdGraph * Graph : Graphs )
{
2019-09-23 07:23:26 -04:00
TArray < UAnimGraphNode_LinkedAnimGraphBase * > LinkedInstanceNodes ;
Graph - > GetNodesOfClass ( LinkedInstanceNodes ) ;
2019-05-22 12:00:20 -04:00
2019-09-23 07:23:26 -04:00
for ( UAnimGraphNode_LinkedAnimGraphBase * LinkedInstanceNode : LinkedInstanceNodes )
2019-05-22 12:00:20 -04:00
{
// If we haven't visited this node, then check it for loops, otherwise if we're pointing to a previously visited node that is in the current instance stack we have a loop
2019-09-23 07:23:26 -04:00
if ( ( ! VisitedNodes . Contains ( LinkedInstanceNode - > NodeGuid ) & & HasInstanceLoop_Recursive ( LinkedInstanceNode , VisitedNodes , NodeStack ) ) | | NodeStack . Contains ( LinkedInstanceNode - > NodeGuid ) )
2019-05-22 12:00:20 -04:00
{
return true ;
}
}
}
}
}
NodeStack . Remove ( CurrNode - > NodeGuid ) ;
return false ;
}
2019-09-23 07:23:26 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : CustomizeDetails ( IDetailLayoutBuilder & DetailBuilder )
2019-05-22 12:00:20 -04:00
{
Super : : CustomizeDetails ( DetailBuilder ) ;
2019-08-08 11:18:26 -04:00
GenerateExposedPinsDetails ( DetailBuilder ) ;
IDetailCategoryBuilder & CategoryBuilder = DetailBuilder . EditCategory ( FName ( TEXT ( " Settings " ) ) ) ;
// Customize InstanceClass
{
TSharedRef < IPropertyHandle > ClassHandle = DetailBuilder . GetProperty ( TEXT ( " Node.InstanceClass " ) , GetClass ( ) ) ;
ClassHandle - > MarkHiddenByCustomization ( ) ;
FDetailWidgetRow & ClassWidgetRow = CategoryBuilder . AddCustomRow ( LOCTEXT ( " FilterStringInstanceClass " , " Instance Class " ) ) ;
ClassWidgetRow . NameContent ( )
[
ClassHandle - > CreatePropertyNameWidget ( )
]
. ValueContent ( )
. MinDesiredWidth ( 250.0f )
[
SNew ( SObjectPropertyEntryBox )
2019-09-23 07:23:26 -04:00
. ObjectPath_UObject ( this , & UAnimGraphNode_LinkedAnimGraphBase : : GetCurrentInstanceBlueprintPath )
2019-08-08 11:18:26 -04:00
. AllowedClass ( UAnimBlueprint : : StaticClass ( ) )
. NewAssetFactories ( TArray < UFactory * > ( ) )
2019-09-23 07:23:26 -04:00
. OnShouldFilterAsset ( FOnShouldFilterAsset : : CreateUObject ( this , & UAnimGraphNode_LinkedAnimGraphBase : : OnShouldFilterInstanceBlueprint ) )
. OnObjectChanged ( FOnSetObject : : CreateUObject ( this , & UAnimGraphNode_LinkedAnimGraphBase : : OnSetInstanceBlueprint , & DetailBuilder ) )
2019-08-08 11:18:26 -04:00
] ;
}
}
2019-09-23 07:23:26 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : GenerateExposedPinsDetails ( IDetailLayoutBuilder & DetailBuilder )
2019-08-08 11:18:26 -04:00
{
2019-05-22 12:00:20 -04:00
// We dont allow multi-select here
if ( DetailBuilder . GetSelectedObjects ( ) . Num ( ) > 1 )
{
DetailBuilder . HideCategory ( TEXT ( " Settings " ) ) ;
return ;
}
2019-07-10 17:06:13 -04:00
// We dont allow multi-select here
if ( DetailBuilder . GetSelectedObjects ( ) . Num ( ) > 1 )
{
DetailBuilder . HideCategory ( TEXT ( " Settings " ) ) ;
return ;
}
2019-12-13 11:07:03 -05:00
TArray < FProperty * > ExposableProperties ;
2019-07-10 17:06:13 -04:00
GetExposableProperties ( ExposableProperties ) ;
if ( ExposableProperties . Num ( ) > 0 )
{
IDetailCategoryBuilder & CategoryBuilder = DetailBuilder . EditCategory ( FName ( TEXT ( " Exposable Properties " ) ) ) ;
FDetailWidgetRow & HeaderWidgetRow = CategoryBuilder . AddCustomRow ( LOCTEXT ( " ExposeAll " , " Expose All " ) ) ;
HeaderWidgetRow . NameContent ( )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " PropertyName " , " Name " ) )
. Font ( IDetailLayoutBuilder : : GetDetailFontBold ( ) )
] ;
HeaderWidgetRow . ValueContent ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. VAlign ( VAlign_Center )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " ExposeAllPropertyValue " , " Expose All " ) )
. Font ( IDetailLayoutBuilder : : GetDetailFontBold ( ) )
]
+ SHorizontalBox : : Slot ( )
. FillWidth ( 1.0f )
. HAlign ( HAlign_Right )
. VAlign ( VAlign_Center )
[
SNew ( SCheckBox )
. IsChecked_UObject ( this , & UAnimGraphNode_CustomProperty : : AreAllPropertiesExposed )
. OnCheckStateChanged_UObject ( this , & UAnimGraphNode_CustomProperty : : OnPropertyExposeAllCheckboxChanged )
]
] ;
2019-12-13 11:07:03 -05:00
for ( FProperty * Property : ExposableProperties )
2019-07-10 17:06:13 -04:00
{
FDetailWidgetRow & PropertyWidgetRow = CategoryBuilder . AddCustomRow ( FText : : FromString ( Property - > GetName ( ) ) ) ;
FName PropertyName = Property - > GetFName ( ) ;
FText PropertyTypeText = GetPropertyTypeText ( Property ) ;
FFormatNamedArguments Args ;
Args . Add ( TEXT ( " PropertyName " ) , FText : : FromName ( PropertyName ) ) ;
Args . Add ( TEXT ( " PropertyType " ) , PropertyTypeText ) ;
FText TooltipText = FText : : Format ( LOCTEXT ( " PropertyTooltipText " , " {PropertyName} \n Type: {PropertyType} " ) , Args ) ;
PropertyWidgetRow . NameContent ( )
[
SNew ( STextBlock )
. Text ( FText : : FromString ( Property - > GetName ( ) ) )
. ToolTipText ( TooltipText )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
] ;
PropertyWidgetRow . ValueContent ( )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. VAlign ( VAlign_Center )
. AutoWidth ( )
[
SNew ( STextBlock )
. Text ( LOCTEXT ( " ExposePropertyValue " , " Expose: " ) )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
]
+ SHorizontalBox : : Slot ( )
. FillWidth ( 1.0f )
. HAlign ( HAlign_Right )
. VAlign ( VAlign_Center )
[
SNew ( SCheckBox )
. IsChecked_UObject ( this , & UAnimGraphNode_CustomProperty : : IsPropertyExposed , PropertyName )
. OnCheckStateChanged_UObject ( this , & UAnimGraphNode_CustomProperty : : OnPropertyExposeCheckboxChanged , PropertyName )
]
] ;
}
}
2019-05-22 12:00:20 -04:00
}
2019-12-13 11:07:03 -05:00
bool UAnimGraphNode_LinkedAnimGraphBase : : IsStructuralProperty ( FProperty * InProperty ) const
2019-05-22 12:00:20 -04:00
{
2019-09-23 07:23:26 -04:00
return InProperty - > GetFName ( ) = = GET_MEMBER_NAME_CHECKED ( FAnimNode_LinkedAnimGraph , InstanceClass ) ;
2019-05-22 12:00:20 -04:00
}
2019-09-23 07:23:26 -04:00
FString UAnimGraphNode_LinkedAnimGraphBase : : GetCurrentInstanceBlueprintPath ( ) const
2019-05-22 12:00:20 -04:00
{
UClass * InstanceClass = GetTargetClass ( ) ;
if ( InstanceClass )
{
UBlueprint * ActualBlueprint = UBlueprint : : GetBlueprintFromClass ( InstanceClass ) ;
if ( ActualBlueprint )
{
return ActualBlueprint - > GetPathName ( ) ;
}
}
return FString ( ) ;
}
2019-09-23 07:23:26 -04:00
bool UAnimGraphNode_LinkedAnimGraphBase : : OnShouldFilterInstanceBlueprint ( const FAssetData & AssetData ) const
2019-05-22 12:00:20 -04:00
{
// Check recursion
if ( AssetData . IsAssetLoaded ( ) & & Cast < UBlueprint > ( AssetData . GetAsset ( ) ) = = GetBlueprint ( ) )
{
return true ;
}
// Check skeleton
FAssetDataTagMapSharedView : : FFindTagResult Result = AssetData . TagsAndValues . FindTag ( " TargetSkeleton " ) ;
if ( Result . IsSet ( ) )
{
if ( UAnimBlueprint * CurrentBlueprint = Cast < UAnimBlueprint > ( GetBlueprint ( ) ) )
{
2021-02-18 18:42:00 -04:00
if ( ! CurrentBlueprint - > TargetSkeleton - > IsCompatibleSkeletonByAssetString ( Result . GetValue ( ) ) )
2019-05-22 12:00:20 -04:00
{
return true ;
}
}
}
return false ;
}
2019-09-23 07:23:26 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : OnSetInstanceBlueprint ( const FAssetData & AssetData , IDetailLayoutBuilder * InDetailBuilder )
2019-05-22 12:00:20 -04:00
{
2019-09-23 07:23:26 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " SetInstanceBlueprint " , " Set Linked Blueprint " ) ) ;
2019-05-22 12:00:20 -04:00
Modify ( ) ;
TSharedRef < IPropertyHandle > ClassHandle = InDetailBuilder - > GetProperty ( TEXT ( " Node.InstanceClass " ) , GetClass ( ) ) ;
if ( UAnimBlueprint * Blueprint = Cast < UAnimBlueprint > ( AssetData . GetAsset ( ) ) )
{
ClassHandle - > SetValue ( Blueprint - > GetAnimBlueprintGeneratedClass ( ) ) ;
}
else
{
ClassHandle - > SetValue ( ( UObject * ) nullptr ) ;
}
}
2019-09-23 07:23:26 -04:00
FPoseLinkMappingRecord UAnimGraphNode_LinkedAnimGraphBase : : GetLinkIDLocation ( const UScriptStruct * NodeType , UEdGraphPin * SourcePin )
2019-05-22 12:00:20 -04:00
{
FPoseLinkMappingRecord Record = Super : : GetLinkIDLocation ( NodeType , SourcePin ) ;
if ( Record . IsValid ( ) )
{
return Record ;
}
else if ( SourcePin - > LinkedTo . Num ( ) > 0 & & SourcePin - > Direction = = EGPD_Input )
{
2019-09-23 07:23:26 -04:00
const FAnimNode_LinkedAnimGraph & Node = * GetLinkedAnimGraphNode ( ) ;
2019-05-22 12:00:20 -04:00
check ( Node . InputPoses . Num ( ) = = Node . InputPoseNames . Num ( ) ) ;
// perform name-based logic for input pose pins
if ( UAnimGraphNode_Base * LinkedNode = Cast < UAnimGraphNode_Base > ( FBlueprintEditorUtils : : FindFirstCompilerRelevantNode ( SourcePin - > LinkedTo [ 0 ] ) ) )
{
2019-12-13 11:07:03 -05:00
FArrayProperty * ArrayProperty = FindFieldChecked < FArrayProperty > ( NodeType , GET_MEMBER_NAME_CHECKED ( FAnimNode_LinkedAnimGraph , InputPoses ) ) ;
2019-05-22 12:00:20 -04:00
int32 ArrayIndex = INDEX_NONE ;
if ( Node . InputPoseNames . Find ( SourcePin - > GetFName ( ) , ArrayIndex ) )
{
check ( Node . InputPoses . IsValidIndex ( ArrayIndex ) ) ;
return FPoseLinkMappingRecord : : MakeFromArrayEntry ( this , LinkedNode , ArrayProperty , ArrayIndex ) ;
}
}
}
return FPoseLinkMappingRecord : : MakeInvalid ( ) ;
}
2021-01-06 09:11:59 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : GetOutputLinkAttributes ( FNodeAttributeArray & OutAttributes ) const
{
// We have the potential to output ALL registered attributes as we can contain any dynamically-linked graph
const UAnimGraphAttributes * AnimGraphAttributes = GetDefault < UAnimGraphAttributes > ( ) ;
AnimGraphAttributes - > ForEachAttribute ( [ & OutAttributes ] ( const FAnimGraphAttributeDesc & InDesc )
{
OutAttributes . Add ( InDesc . Name ) ;
} ) ;
}
2021-01-25 08:43:19 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : OnCopyTermDefaultsToDefaultObject ( IAnimBlueprintCopyTermDefaultsContext & InCompilationContext , IAnimBlueprintNodeCopyTermDefaultsContext & InPerNodeContext , IAnimBlueprintGeneratedClassCompiledData & OutCompiledData )
{
2021-06-17 08:59:23 -04:00
Super : : OnCopyTermDefaultsToDefaultObject ( InCompilationContext , InPerNodeContext , OutCompiledData ) ;
2021-01-25 08:43:19 -04:00
UAnimGraphNode_LinkedAnimGraphBase * TrueNode = InCompilationContext . GetMessageLog ( ) . FindSourceObjectTypeChecked < UAnimGraphNode_LinkedAnimGraphBase > ( this ) ;
FAnimNode_LinkedAnimGraph * DestinationNode = reinterpret_cast < FAnimNode_LinkedAnimGraph * > ( InPerNodeContext . GetDestinationPtr ( ) ) ;
DestinationNode - > NodeIndex = InPerNodeContext . GetNodePropertyIndex ( ) ;
}
2021-04-22 04:57:09 -04:00
void UAnimGraphNode_LinkedAnimGraphBase : : GetRequiredExtensions ( TArray < TSubclassOf < UAnimBlueprintExtension > > & OutExtensions ) const
{
OutExtensions . Add ( UAnimBlueprintExtension_LinkedAnimGraph : : StaticClass ( ) ) ;
}
2021-05-24 06:55:32 -04:00
TSharedPtr < FEdGraphSchemaAction > UAnimGraphNode_LinkedAnimGraphBase : : GetEventNodeAction ( const FText & ActionCategory )
{
TSharedPtr < FEdGraphSchemaAction_K2Event > NodeAction = MakeShareable ( new FEdGraphSchemaAction_K2Event ( ActionCategory , GetNodeTitle ( ENodeTitleType : : ListView ) , GetTooltipText ( ) , 0 ) ) ;
NodeAction - > NodeTemplate = this ;
return NodeAction ;
}
2019-05-22 12:00:20 -04:00
# undef LOCTEXT_NAMESPACE