void UAnimGraphNode_SequencePlayer::GetMenuActions(FBlueprintActionDatabaseRegistrar& ActionRegistrar) const { auto LoadedAssetSetup = [](UEdGraphNode* NewNode, bool /*bIsTemplateNode*/, TWeakObjectPtr<UAnimSequence> SequencePtr) { UAnimGraphNode_SequencePlayer* SequencePlayerNode = CastChecked<UAnimGraphNode_SequencePlayer>(NewNode); SequencePlayerNode->Node.Sequence = SequencePtr.Get(); }; auto UnloadedAssetSetup = [](UEdGraphNode* NewNode, bool bIsTemplateNode, const FAssetData AssetData) { UAnimGraphNode_SequencePlayer* SequencePlayerNode = CastChecked<UAnimGraphNode_SequencePlayer>(NewNode); if (bIsTemplateNode) { if (const FString* SkeletonTag = AssetData.TagsAndValues.Find(TEXT("Skeleton"))) { SequencePlayerNode->UnloadedSkeletonName = *SkeletonTag; } } else { UAnimSequence* Sequence = Cast<UAnimSequence>(AssetData.GetAsset()); check(Sequence != nullptr); SequencePlayerNode->Node.Sequence = Sequence; } }; const UObject* QueryObject = ActionRegistrar.GetActionKeyFilter(); if (QueryObject == nullptr) { FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry")); // define a filter to help in pulling UAnimSequence asset data from the registry FARFilter Filter; Filter.ClassNames.Add(UAnimSequence::StaticClass()->GetFName()); Filter.bRecursiveClasses = true; // Find matching assets and add an entry for each one TArray<FAssetData> SequenceList; AssetRegistryModule.Get().GetAssets(Filter, /*out*/SequenceList); for (auto AssetIt = SequenceList.CreateConstIterator(); AssetIt; ++AssetIt) { const FAssetData& Asset = *AssetIt; UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass()); if (Asset.IsAssetLoaded()) { TWeakObjectPtr<UAnimSequence> AnimSequence = Cast<UAnimSequence>(Asset.GetAsset()); NodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(LoadedAssetSetup, AnimSequence); NodeSpawner->DefaultMenuSignature.MenuName = GetTitleGivenAssetInfo(FText::FromName(AnimSequence->GetFName()), AnimSequence->IsValidAdditive()); } else { NodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(UnloadedAssetSetup, Asset); NodeSpawner->DefaultMenuSignature.MenuName = GetTitleGivenAssetInfo(FText::FromName(Asset.AssetName), /*bKnownToBeAdditive =*/false); } ActionRegistrar.AddBlueprintAction(Asset, NodeSpawner); } } else if (const UAnimSequence* AnimSequence = Cast<UAnimSequence>(QueryObject)) { UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass()); TWeakObjectPtr<UAnimSequence> SequencePtr = AnimSequence; NodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(LoadedAssetSetup, SequencePtr); NodeSpawner->DefaultMenuSignature.MenuName = GetTitleGivenAssetInfo(FText::FromName(AnimSequence->GetFName()), AnimSequence->IsValidAdditive()); ActionRegistrar.AddBlueprintAction(QueryObject, NodeSpawner); } else if (QueryObject == GetClass()) { FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry")); // define a filter to help in pulling UAnimSequence asset data from the registry FARFilter Filter; Filter.ClassNames.Add(UAnimSequence::StaticClass()->GetFName()); Filter.bRecursiveClasses = true; // Find matching assets and add an entry for each one TArray<FAssetData> SequenceList; AssetRegistryModule.Get().GetAssets(Filter, /*out*/SequenceList); for (auto AssetIt = SequenceList.CreateConstIterator(); AssetIt; ++AssetIt) { const FAssetData& Asset = *AssetIt; if (Asset.IsAssetLoaded()) { continue; } UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create(GetClass()); NodeSpawner->CustomizeNodeDelegate = UBlueprintNodeSpawner::FCustomizeNodeDelegate::CreateStatic(UnloadedAssetSetup, Asset); NodeSpawner->DefaultMenuSignature.MenuName = GetTitleGivenAssetInfo(FText::FromName(Asset.AssetName), /*bKnownToBeAdditive =*/false); ActionRegistrar.AddBlueprintAction(Asset, NodeSpawner); } } }