void UAnimationTransitionSchema::GetSourceStateActions(FGraphContextMenuBuilder& ContextMenuBuilder) const { if ((ContextMenuBuilder.FromPin == NULL) || ((ContextMenuBuilder.FromPin->Direction == EGPD_Input) && (ContextMenuBuilder.FromPin->PinType.PinCategory == PC_Float))) { // Find the source state associated with this transition UAnimBlueprint* Blueprint = CastChecked<UAnimBlueprint>(FBlueprintEditorUtils::FindBlueprintForGraph(ContextMenuBuilder.CurrentGraph)); if (UAnimBlueprintGeneratedClass* AnimBlueprintClass = Blueprint->GetAnimBlueprintSkeletonClass()) { if (UAnimStateTransitionNode* TransNode = GetTransitionNodeFromGraph(AnimBlueprintClass->GetAnimBlueprintDebugData(), ContextMenuBuilder.CurrentGraph)) { if (UAnimStateNode* SourceStateNode = Cast<UAnimStateNode>(TransNode->GetPreviousState())) { // Offer options from the source state // Sequence player positions ETransitionGetter::Type SequenceSpecificGetters[] = { ETransitionGetter::AnimationAsset_GetCurrentTime, ETransitionGetter::AnimationAsset_GetLength, ETransitionGetter::AnimationAsset_GetCurrentTimeFraction, ETransitionGetter::AnimationAsset_GetTimeFromEnd, ETransitionGetter::AnimationAsset_GetTimeFromEndFraction }; TArray<UK2Node*> AssetPlayers; SourceStateNode->BoundGraph->GetNodesOfClassEx<UAnimGraphNode_Base, UK2Node>(/*out*/ AssetPlayers); const FString Category_AssetPlayer(TEXT("Asset Player")); for (int32 TypeIndex = 0; TypeIndex < ARRAY_COUNT(SequenceSpecificGetters); ++TypeIndex) { for (auto NodeIt = AssetPlayers.CreateConstIterator(); NodeIt; ++NodeIt) { UAnimGraphNode_Base* AnimNode = CastChecked<UAnimGraphNode_Base>(*NodeIt); if (AnimNode->DoesSupportTimeForTransitionGetter()) { UK2Node_TransitionRuleGetter* NodeTemplate = ContextMenuBuilder.CreateTemplateNode<UK2Node_TransitionRuleGetter>(); FString AssetName; UAnimationAsset * AnimAsset = AnimNode->GetAnimationAsset(); if (AnimAsset) { NodeTemplate->AssociatedAnimAssetPlayerNode = AnimNode; AssetName = AnimAsset->GetName(); } NodeTemplate->GetterType = SequenceSpecificGetters[TypeIndex]; FFormatNamedArguments Args; Args.Add(TEXT("NodeName"), UK2Node_TransitionRuleGetter::GetFriendlyName(NodeTemplate->GetterType)); Args.Add(TEXT("AssetName"), FText::FromString(AssetName)); FText Title = FText::Format(LOCTEXT("TransitionFor", "{NodeName} for '{AssetName}'"), Args); TSharedPtr<FEdGraphSchemaAction_K2NewNode> Action = FK2ActionMenuBuilder::AddNewNodeAction(ContextMenuBuilder, Category_AssetPlayer, Title, NodeTemplate->GetTooltipText().ToString(), 0, NodeTemplate->GetKeywords()); Action->NodeTemplate = NodeTemplate; } } } // Non-sequence specific ones ETransitionGetter::Type NonSpecificGetters[] = { ETransitionGetter::CurrentTransitionDuration, ETransitionGetter::CurrentState_ElapsedTime, ETransitionGetter::CurrentState_GetBlendWeight }; for (int32 TypeIndex = 0; TypeIndex < ARRAY_COUNT(NonSpecificGetters); ++TypeIndex) { FString Category_Transition(TEXT("Transition")); UK2Node_TransitionRuleGetter* NodeTemplate = ContextMenuBuilder.CreateTemplateNode<UK2Node_TransitionRuleGetter>(); NodeTemplate->GetterType = NonSpecificGetters[TypeIndex]; FText Title = UK2Node_TransitionRuleGetter::GetFriendlyName(NodeTemplate->GetterType); TSharedPtr<FEdGraphSchemaAction_K2NewNode> Action = FK2ActionMenuBuilder::AddNewNodeAction(ContextMenuBuilder, Category_Transition, Title, NodeTemplate->GetTooltipText().ToString(), 0, NodeTemplate->GetKeywords()); Action->NodeTemplate = NodeTemplate; } } } } } }
void UAnimationGraphSchema::GetStateMachineMenuItems(FGraphContextMenuBuilder& ContextMenuBuilder) const { // Show state machine helpers if ((ContextMenuBuilder.FromPin == NULL) || ((ContextMenuBuilder.FromPin->Direction == EGPD_Input) && (ContextMenuBuilder.FromPin->PinType.PinCategory == PC_Float))) { FString StateCategory(TEXT("State Machines")); // Create the additional entries to get state information TArray<UAnimStateNode*> States; UBlueprint* CurrentBlueprint = FBlueprintEditorUtils::FindBlueprintForGraphChecked(ContextMenuBuilder.CurrentGraph); FBlueprintEditorUtils::GetAllNodesOfClass(CurrentBlueprint, /*out*/ States); for (auto StateIt = States.CreateIterator(); StateIt; ++StateIt) { UAnimStateNode* StateNode = *StateIt; UK2Node_TransitionRuleGetter* NodeTemplate = ContextMenuBuilder.CreateTemplateNode<UK2Node_TransitionRuleGetter>(); NodeTemplate->AssociatedStateNode = StateNode; NodeTemplate->GetterType = ETransitionGetter::ArbitraryState_GetBlendWeight; const FString OwnerName = StateNode->GetOuter()->GetName(); const FString Title = FString::Printf(TEXT("Current %s for state '%s.%s'"), *UK2Node_TransitionRuleGetter::GetFriendlyName(NodeTemplate->GetterType), *OwnerName, *StateNode->GetStateName()); TSharedPtr<FEdGraphSchemaAction_K2NewNode> Action = FK2ActionMenuBuilder::AddNewNodeAction(ContextMenuBuilder, StateCategory, Title, NodeTemplate->GetTooltip(), 0, NodeTemplate->GetKeywords()); Action->NodeTemplate = NodeTemplate; } } }