#pragma once #include "CoreMinimal.h" #include "WingHandler.h" #include "WingServer.h" #include "WingFetcher.h" #include "WingProperty.h" #include "WingJson.h" #include "WingUtils.h" #include "EdGraph/EdGraphPin.h" #include "EdGraphSchema_K2.h" #include "MaterialGraph/MaterialGraphSchema.h" #include "GraphNode_SetDefaults.generated.h" // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- USTRUCT() struct FSetNodeDefaultEntry { GENERATED_BODY() UPROPERTY() FString Node; UPROPERTY() FString Name; UPROPERTY() FString Value; }; UCLASS() class UWing_GraphNode_SetDefaults : public UObject, public IWingHandler { GENERATED_BODY() public: UPROPERTY(meta=(Description="Target graph")) FString Graph; UPROPERTY(meta=(Description="Array of {node, name, value} objects")) FWingJsonArray Pins; virtual FString GetDescription() const override { return TEXT("Set the default value of input pins or material expression properties on nodes."); } // ----------------------------------------------------------------------- // K2 graphs: set pin default values. // ----------------------------------------------------------------------- void HandleK2Entry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj, const UEdGraphSchema_K2* K2Schema) { WingFetcher F(GraphObj); UEdGraphPin* Pin = F.Node(Entry.Node).Pin(Entry.Name).Cast(); if (!Pin) return; UEdGraphNode* Node = Pin->GetOwningNode(); if (Pin->Direction != EGPD_Input) { UWingServer::Printf(TEXT("error: %s is an output pin\n"), *WingUtils::FormatName(Pin)); return; } Pin->Modify(); FString UseDefaultValue; TObjectPtr UseDefaultObject = nullptr; FText UseDefaultText; K2Schema->GetPinDefaultValuesFromString(Pin->PinType, Node, Entry.Value, UseDefaultValue, UseDefaultObject, UseDefaultText, false); FString Error = K2Schema->IsPinDefaultValid(Pin, UseDefaultValue, UseDefaultObject, UseDefaultText); if (!Error.IsEmpty()) { UWingServer::Printf(TEXT("error: %s: %s\n"), *WingUtils::FormatName(Pin), *Error); return; } UWingServer::AddTouchedObject(Node); K2Schema->TrySetDefaultValue(*Pin, Entry.Value); } // ----------------------------------------------------------------------- // Material graphs: set material expression properties. // ----------------------------------------------------------------------- void HandleMaterialEntry(const FSetNodeDefaultEntry& Entry, UEdGraph* GraphObj) { WingFetcher F(GraphObj); UEdGraphNode* Node = F.Node(Entry.Node).Cast(); if (!Node) return; TArray All = WingProperty::GetAll(Node, CPF_Edit); WingProperty P = WingProperty::FindOneExactMatch(All, Entry.Name); if (!P) return; UWingServer::AddTouchedObject(Node); if (!P.SetText(Entry.Value)) return; } // ----------------------------------------------------------------------- virtual void Handle() override { // Fetch the graph once. WingFetcher GraphFetcher; UEdGraph* GraphObj = GraphFetcher.Walk(Graph).Cast(); if (!GraphObj) return; const UEdGraphSchema* Schema = GraphObj->GetSchema(); const UEdGraphSchema_K2* K2Schema = Cast(Schema); const UMaterialGraphSchema* MGSchema = Cast(Schema); if (!K2Schema && !MGSchema) { UWingServer::Printf(TEXT("error: unsupported graph schema %s\n"), *Schema->GetClass()->GetName()); return; } for (const TSharedPtr& PinVal : Pins.Array) { FSetNodeDefaultEntry Entry; if (!WingJson::PopulateFromJson(FSetNodeDefaultEntry::StaticStruct(), &Entry, PinVal)) continue; if (K2Schema) HandleK2Entry(Entry, GraphObj, K2Schema); else if (MGSchema) HandleMaterialEntry(Entry, GraphObj); } UWingServer::Printf(TEXT("Done.\n")); } };