BlueprintGraph_Create
This commit is contained in:
@@ -1,116 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "WingServer.h"
|
|
||||||
#include "WingHandler.h"
|
|
||||||
#include "WingFetcher.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "Engine/Blueprint.h"
|
|
||||||
#include "EdGraph/EdGraph.h"
|
|
||||||
#include "EdGraph/EdGraphNode.h"
|
|
||||||
#include "EdGraphSchema_K2.h"
|
|
||||||
#include "K2Node_CustomEvent.h"
|
|
||||||
#include "Kismet2/BlueprintEditorUtils.h"
|
|
||||||
#include "BlueprintGraph_Create.generated.h"
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class UWing_BlueprintGraph_Create : public UObject, public IWingHandler
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
|
||||||
FString Blueprint;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Name for the new graph"))
|
|
||||||
FString Graph;
|
|
||||||
|
|
||||||
UPROPERTY(meta=(Description="Type of graph: function, macro, or customEvent"))
|
|
||||||
FString GraphType;
|
|
||||||
|
|
||||||
virtual FString GetDescription() const override
|
|
||||||
{
|
|
||||||
return TEXT("Create a new function, macro, or custom event graph in a Blueprint.");
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Handle() override
|
|
||||||
{
|
|
||||||
if (GraphType != TEXT("function") && GraphType != TEXT("macro") && GraphType != TEXT("customEvent"))
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("ERROR: Invalid GraphType '%s'. Valid values: function, macro, customEvent\n"), *GraphType);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WingFetcher F;
|
|
||||||
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
|
||||||
if (!BP) return;
|
|
||||||
|
|
||||||
// Check graph name uniqueness
|
|
||||||
if (!WingUtils::FindExactlyNoneNamed(Graph, WingUtils::AllGraphs(BP), TEXT("Graph")))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// For custom events, also check for existing custom events with the same name
|
|
||||||
if (GraphType == TEXT("customEvent"))
|
|
||||||
{
|
|
||||||
for (UK2Node_CustomEvent* CE : WingUtils::AllNodes<UK2Node_CustomEvent>(BP))
|
|
||||||
{
|
|
||||||
if (CE->CustomFunctionName == FName(*Graph))
|
|
||||||
{
|
|
||||||
UWingServer::Printf(TEXT("ERROR: A custom event named '%s' already exists in %s\n"), *Graph, *WingUtils::FormatName(BP));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GraphType == TEXT("function"))
|
|
||||||
{
|
|
||||||
UEdGraph* NewGraph = FBlueprintEditorUtils::CreateNewGraph(BP, FName(*Graph),
|
|
||||||
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
|
|
||||||
if (!NewGraph)
|
|
||||||
{
|
|
||||||
UWingServer::Print(TEXT("ERROR: Failed to create function graph\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FBlueprintEditorUtils::AddFunctionGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromObject=*/static_cast<UClass*>(nullptr));
|
|
||||||
UWingServer::Printf(TEXT("Created function graph: %s\n"), *WingUtils::FormatName(NewGraph));
|
|
||||||
}
|
|
||||||
else if (GraphType == TEXT("macro"))
|
|
||||||
{
|
|
||||||
UEdGraph* NewGraph = FBlueprintEditorUtils::CreateNewGraph(BP, FName(*Graph),
|
|
||||||
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
|
|
||||||
if (!NewGraph)
|
|
||||||
{
|
|
||||||
UWingServer::Print(TEXT("ERROR: Failed to create macro graph\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FBlueprintEditorUtils::AddMacroGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromClass=*/nullptr);
|
|
||||||
UWingServer::Printf(TEXT("Created macro graph: %s\n"), *WingUtils::FormatName(NewGraph));
|
|
||||||
}
|
|
||||||
else // customEvent
|
|
||||||
{
|
|
||||||
UEdGraph* EventGraph = nullptr;
|
|
||||||
if (BP->UbergraphPages.Num() > 0)
|
|
||||||
EventGraph = BP->UbergraphPages[0];
|
|
||||||
if (!EventGraph)
|
|
||||||
{
|
|
||||||
UWingServer::Print(TEXT("ERROR: Blueprint has no EventGraph to add a custom event to\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UK2Node_CustomEvent* NewEvent = NewObject<UK2Node_CustomEvent>(EventGraph);
|
|
||||||
NewEvent->CustomFunctionName = FName(*Graph);
|
|
||||||
NewEvent->bIsEditable = true;
|
|
||||||
EventGraph->AddNode(NewEvent, /*bFromUI=*/false, /*bSelectNewNode=*/false);
|
|
||||||
NewEvent->CreateNewGuid();
|
|
||||||
NewEvent->PostPlacedNewNode();
|
|
||||||
NewEvent->AllocateDefaultPins();
|
|
||||||
UWingServer::Printf(TEXT("Created custom event: %s\n"), *WingUtils::FormatName(NewEvent));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "WingServer.h"
|
||||||
|
#include "WingHandler.h"
|
||||||
|
#include "WingFetcher.h"
|
||||||
|
#include "WingUtils.h"
|
||||||
|
#include "WingFunctionArgs.h"
|
||||||
|
#include "Engine/Blueprint.h"
|
||||||
|
#include "EdGraph/EdGraph.h"
|
||||||
|
#include "EdGraph/EdGraphNode.h"
|
||||||
|
#include "K2Node_EditablePinBase.h"
|
||||||
|
#include "K2Node_FunctionResult.h"
|
||||||
|
#include "EdGraphSchema_K2.h"
|
||||||
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
|
#include "BlueprintGraph_Create.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class UWing_BlueprintGraph_Create : public UObject, public IWingHandler
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(meta=(Description="Blueprint name or package path"))
|
||||||
|
FString Blueprint;
|
||||||
|
|
||||||
|
UPROPERTY(meta=(Description="Name for the new graph"))
|
||||||
|
FString Graph;
|
||||||
|
|
||||||
|
UPROPERTY(meta=(Description="Type of graph: function or macro"))
|
||||||
|
FString GraphType;
|
||||||
|
|
||||||
|
UPROPERTY(meta=(Description="Arguments expressed as: int x,float y"))
|
||||||
|
FString Arguments;
|
||||||
|
|
||||||
|
UPROPERTY(meta=(Description="Return values expressed as: int x,float y"))
|
||||||
|
FString ReturnValues;
|
||||||
|
|
||||||
|
virtual FString GetDescription() const override
|
||||||
|
{
|
||||||
|
return TEXT("Create a new function or macro graph in a Blueprint.");
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Handle() override
|
||||||
|
{
|
||||||
|
if (GraphType != TEXT("function") && GraphType != TEXT("macro"))
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT("ERROR: Invalid GraphType '%s'. Valid values: function, macro\n"), *GraphType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WingFetcher F;
|
||||||
|
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>();
|
||||||
|
if (!BP) return;
|
||||||
|
|
||||||
|
// Check that this graph type is valid for this blueprint type
|
||||||
|
if (BP->BlueprintType == BPTYPE_Interface)
|
||||||
|
{
|
||||||
|
UWingServer::Print(TEXT("ERROR: Cannot add graphs to interface blueprints.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (BP->BlueprintType == BPTYPE_MacroLibrary && GraphType == TEXT("function"))
|
||||||
|
{
|
||||||
|
UWingServer::Print(TEXT("ERROR: Macro libraries cannot contain functions.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (BP->BlueprintType == BPTYPE_FunctionLibrary && GraphType == TEXT("macro"))
|
||||||
|
{
|
||||||
|
UWingServer::Print(TEXT("ERROR: Function libraries cannot contain macros.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check graph name uniqueness and legality
|
||||||
|
if (!WingUtils::FindExactlyNoneNamed(Graph, WingUtils::AllGraphs(BP), TEXT("Graph")))
|
||||||
|
return;
|
||||||
|
FString InternalName = WingUtils::CheckProposedName(Graph);
|
||||||
|
if (InternalName.IsEmpty()) return;
|
||||||
|
|
||||||
|
// Validate argument and return value types before making changes
|
||||||
|
if (!Arguments.IsEmpty() && !WingFunctionArgs::CheckArgs(Arguments)) return;
|
||||||
|
if (!ReturnValues.IsEmpty() && !WingFunctionArgs::CheckArgs(ReturnValues)) return;
|
||||||
|
|
||||||
|
// Create the Graph
|
||||||
|
UEdGraph* NewGraph = FBlueprintEditorUtils::CreateNewGraph(BP, FName(InternalName),
|
||||||
|
UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
|
||||||
|
if (!NewGraph)
|
||||||
|
{
|
||||||
|
UWingServer::Print(TEXT("ERROR: Failed to create graph\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GraphType == TEXT("function"))
|
||||||
|
{
|
||||||
|
FBlueprintEditorUtils::AddFunctionGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromObject=*/static_cast<UClass*>(nullptr));
|
||||||
|
FBlueprintEditorUtils::FindOrCreateFunctionResultNode(FBlueprintEditorUtils::GetEntryNode(NewGraph));
|
||||||
|
}
|
||||||
|
else if (GraphType == TEXT("macro"))
|
||||||
|
{
|
||||||
|
FBlueprintEditorUtils::AddMacroGraph(BP, NewGraph, /*bIsUserCreated=*/true, /*SignatureFromClass=*/nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try GetEntryAndResultNodes first (works for both functions and macros)
|
||||||
|
TWeakObjectPtr<UK2Node_EditablePinBase> Entry;
|
||||||
|
TWeakObjectPtr<UK2Node_EditablePinBase> Exit;
|
||||||
|
FBlueprintEditorUtils::GetEntryAndResultNodes(NewGraph, Entry, Exit);
|
||||||
|
if ((Entry == nullptr) || (Exit == nullptr))
|
||||||
|
{
|
||||||
|
UWingServer::Printf(TEXT("Could not get graph entry and exit nodes.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!WingFunctionArgs::SetArgs(Entry.Get(), Arguments)) return;
|
||||||
|
if (!WingFunctionArgs::SetArgs(Exit.Get(), ReturnValues)) return;
|
||||||
|
|
||||||
|
UWingServer::Printf(TEXT("Created %s graph: %s\n"), *GraphType, *WingUtils::FormatName(NewGraph));
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "WingTypes.h"
|
#include "WingTypes.h"
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
|
#include "Kismet2/BlueprintEditorUtils.h"
|
||||||
|
|
||||||
bool WingFunctionArgs::HasArgs(UEdGraphNode* Node)
|
bool WingFunctionArgs::HasArgs(UEdGraphNode* Node)
|
||||||
{
|
{
|
||||||
@@ -117,3 +118,4 @@ bool WingFunctionArgs::CheckArgs(const FString &Args)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user