#pragma once #include "CoreMinimal.h" #include "WingServer.h" #include "WingBasics.h" #include "WingFetcher.h" #include "WingProperty.h" #include "WingUtils.h" #include "EdGraph/EdGraph.h" #include "EdGraph/EdGraphSchema.h" #include "EdGraph/EdGraphPin.h" #include "GraphPin_Connect.generated.h" // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- USTRUCT() struct FConnectPinsEntry { GENERATED_BODY() UPROPERTY() FString SourcePin; UPROPERTY() FString TargetPin; }; UCLASS() class UWing_GraphPin_Connect : public UWingHandler { GENERATED_BODY() public: UPROPERTY(EditAnywhere, meta=(Description="Target graph")) FString Graph; UPROPERTY(EditAnywhere, meta=(Description="Array of {sourcePin, targetPin} objects")) FWingJsonArray Connections; virtual void Register() override { UWingServer::AddHandler(this, TEXT("Connect pins between nodes in a graph (Blueprint or Material). " "Pin IDs use fetcher path syntax relative to the graph, eg: " "node:K2Node_CallFunction_0,pin:ReturnValue")); } virtual void Handle() override { WingFetcher F(WingOut::Stdout); UEdGraph* G = F.Walk(Graph).Cast(); if (!G) return; int32 SuccessCount = 0; int32 TotalCount = Connections.Array.Num(); FConnectPinsEntry Entry; TArray EntryProps = FWingProperty::GetAll(nullptr, &Entry, FConnectPinsEntry::StaticStruct(), true); for (const TSharedPtr& ConnVal : Connections.Array) { if (!FWingProperty::PopulateFromJson(EntryProps, *ConnVal, false, WingOut::Stdout)) continue; WingFetcher FS(G, WingOut::Stdout); UWingGraphPinRef* SourcePinRef = FS.Walk(Entry.SourcePin).Cast(); if (!SourcePinRef) continue; UEdGraphPin* SourcePin = WingUtils::CheckGetPin(SourcePinRef->Node, SourcePinRef->PinName, WingOut::Stdout); if (!SourcePin) continue; WingFetcher FT(G, WingOut::Stdout); UWingGraphPinRef* TargetPinRef = FT.Walk(Entry.TargetPin).Cast(); if (!TargetPinRef) continue; UEdGraphPin* TargetPin = WingUtils::CheckGetPin(TargetPinRef->Node, TargetPinRef->PinName, WingOut::Stdout); if (!TargetPin) continue; const UEdGraphSchema* Schema = G->GetSchema(); const FPinConnectionResponse Response = Schema->CanCreateConnection(SourcePin, TargetPin); if (Response.Response == CONNECT_RESPONSE_DISALLOW) { WingOut::Stdout.Printf(TEXT("error: Cannot connect %s.%s to %s.%s: %s\n"), *WingUtils::FormatName(SourcePin->GetOwningNode()), *WingUtils::FormatName(SourcePin), *WingUtils::FormatName(TargetPin->GetOwningNode()), *WingUtils::FormatName(TargetPin), *Response.Message.ToString()); continue; } Schema->TryCreateConnection(SourcePin, TargetPin); SuccessCount++; } WingOut::Stdout.Printf(TEXT("Connected %d/%d pins.\n"), SuccessCount, TotalCount); } };