#pragma once #include "CoreMinimal.h" #include "MCPServer.h" #include "MCPHandler.h" #include "MCPFetcher.h" #include "MCPUtils.h" #include "Kismet2/KismetEditorUtilities.h" #include "Animation/AnimBlueprint.h" #include "AnimStateNode.h" #include "AnimStateTransitionNode.h" #include "AnimationStateMachineGraph.h" #include "StateMachine_AddTransition.generated.h" // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- UCLASS() class UMCP_StateMachine_AddTransition : public UObject, public IMCPHandler { GENERATED_BODY() public: UPROPERTY(meta=(Description="Animation Blueprint package path")) FString Blueprint; UPROPERTY(meta=(Description="State machine graph name")) FString Graph; UPROPERTY(meta=(Description="Name of the source state")) FString FromState; UPROPERTY(meta=(Description="Name of the target state")) FString ToState; UPROPERTY(meta=(Optional, Description="Crossfade duration in seconds")) float CrossfadeDuration = 0.0f; UPROPERTY(meta=(Optional, Description="Transition priority order")) int32 Priority = 0; UPROPERTY(meta=(Optional, Description="Whether the transition is bidirectional")) bool BBidirectional = false; virtual FString GetDescription() const override { return TEXT("Add a transition between two states in an animation state machine graph."); } virtual void Handle() override { MCPFetcher F; UAnimBlueprint* AnimBP = F.Asset(Blueprint).Cast(); if (!AnimBP) return; UAnimationStateMachineGraph* SMGraph = MCPUtils::FindStateMachineGraph(AnimBP, Graph); if (!SMGraph) { UMCPServer::Printf(TEXT("ERROR: State machine graph '%s' not found in '%s'\n"), *Graph, *MCPUtils::FormatName(AnimBP)); return; } UAnimStateNode* FromStateNode = MCPUtils::FindStateByName(SMGraph, FromState); if (!FromStateNode) return; UAnimStateNode* ToStateNode = MCPUtils::FindStateByName(SMGraph, ToState); if (!ToStateNode) return; // Create transition node UAnimStateTransitionNode* TransNode = NewObject(SMGraph); TransNode->CreateNewGuid(); TransNode->PostPlacedNewNode(); TransNode->AllocateDefaultPins(); // Position between the two states TransNode->NodePosX = (FromStateNode->NodePosX + ToStateNode->NodePosX) / 2; TransNode->NodePosY = (FromStateNode->NodePosY + ToStateNode->NodePosY) / 2; SMGraph->AddNode(TransNode, false, false); TransNode->SetFlags(RF_Transactional); // Connect: FromState output -> Transition input, Transition output -> ToState input TransNode->CreateConnections(FromStateNode, ToStateNode); // Set optional properties TransNode->CrossfadeDuration = CrossfadeDuration; TransNode->PriorityOrder = Priority; TransNode->Bidirectional = BBidirectional; // Compile and save FKismetEditorUtilities::CompileBlueprint(AnimBP); MCPUtils::SaveBlueprintPackage(AnimBP); UMCPServer::Printf(TEXT("Created transition %s -> %s: %s\n"), *FromState, *ToState, *MCPUtils::FormatName(TransNode)); } };