More fixes to blueprint exporter.

This commit is contained in:
2026-02-16 21:02:01 -05:00
parent 15997aee62
commit 55ad662d3f
5 changed files with 55 additions and 25 deletions

View File

@@ -115,6 +115,7 @@ Do not use git to make changes (commit, push, branch, etc.). Read-only git comma
## Coding Conventions ## Coding Conventions
- Prefer early returns and `continue` to reduce nesting (never-nester style).
- Do not use static functions in Unreal code. Use class methods or namespace-scoped functions instead. - Do not use static functions in Unreal code. Use class methods or namespace-scoped functions instead.
- Use `LogLuprexIntegration` for log messages, not `LogTemp`. - Use `LogLuprexIntegration` for log messages, not `LogTemp`.
- When writing UFUNCTIONs that take an `AActor*`, `UObject*`, or similar "self" parameter, add `DefaultToSelf` meta to that pin. Most functions should have this on the obvious pin so the user doesn't have to manually wire it in blueprints. - When writing UFUNCTIONs that take an `AActor*`, `UObject*`, or similar "self" parameter, add `DefaultToSelf` meta to that pin. Most functions should have this on the obvious pin so the user doesn't have to manually wire it in blueprints.

Binary file not shown.

View File

@@ -10,35 +10,34 @@ The exporter class (`Source/Integration/BlueprintExporter.h/.cpp`) processes one
## Output Format ## Output Format
Each file has two sections: The graph file is written to `Saved/BlueprintExports/<BlueprintName>/<GraphName>.txt`. A details file with node-name-to-GUID mappings is written to `Saved/BlueprintExports/<BlueprintName>/DETAILS/<GraphName>.txt`.
**NodeList** maps readable node names to GUIDs: Every line in the graph file starts with a keyword, making it easy to parse. The format is:
```
NodeList:
Event_Tick = 44BAE739C72246DD9E9A72803C3B67CA
Set_Tick_Delta_Seconds = 204486800C0C4906A456A378F9F7ADE4
```
**Graph** shows the flow with pins and connections:
``` ```
Graph: node Event_Tick
return Output_Delegate, Delta_Seconds
Event_Tick
return Output_Delegate,Delta_Seconds
goto Set_Tick_Delta_Seconds goto Set_Tick_Delta_Seconds
Set_Tick_Delta_Seconds node Set_Tick_Delta_Seconds
Real Tick_Delta_Seconds = Event_Tick.Delta_Seconds input Real Tick_Delta_Seconds = Event_Tick.Delta_Seconds
return Output_Get return Output_Get
goto CallFunctionByName goto CallFunctionByName
``` ```
- Input data pins: `Type Name = Source` where Source is a `Node.Pin` reference, a literal value, `<self>`, or `<default>`. ### Line Keywords
- Output data pins: `return Pin1,Pin2`.
- Exec flow: `goto Target` (single output), `goto Target if PinName` (multiple outputs), or `then goto`/`else goto` (branch nodes). - `node Name` — starts a new node block.
- `input Type Name = Source` — an input data pin. Source is a `Node.Pin` reference, a literal value, `<self>`, or `<default>`.
- `return Pin1, Pin2` — output data pins.
- `goto Target` — exec flow (single output).
- `goto-if PinName Target` — exec flow (multiple outputs, e.g. branch true/false).
- `// comment text` — comment node.
### Special Handling
- String defaults are shown in quotes. - String defaults are shown in quotes.
- Variable get nodes are inlined (the variable name appears directly at the point of use). - Variable get nodes are inlined (the variable name appears directly at the point of use rather than as a separate node).
- Comment nodes appear as `// comment text`.
- Knot (reroute) nodes are followed through transparently. - Knot (reroute) nodes are followed through transparently.
## Node Ordering ## Node Ordering

View File

@@ -11,12 +11,14 @@
#include "EdGraphNode_Comment.h" #include "EdGraphNode_Comment.h"
#include "K2Node_VariableGet.h" #include "K2Node_VariableGet.h"
#include "K2Node_CallFunction.h" #include "K2Node_CallFunction.h"
#include "K2Node_FunctionEntry.h"
FlxBlueprintExporter::FlxBlueprintExporter(UEdGraph* InGraph) FlxBlueprintExporter::FlxBlueprintExporter(UEdGraph* InGraph)
: Graph(InGraph) : Graph(InGraph)
{ {
SortNodes(); SortNodes();
AssignNodeNames(); AssignNodeNames();
EmitLocalVariables();
EmitNodeList(); EmitNodeList();
EmitGraph(); EmitGraph();
} }
@@ -33,20 +35,27 @@ FString FlxBlueprintExporter::SanitizeName(const FString& Title)
return Result.IsEmpty() ? TEXT("_") : Result; return Result.IsEmpty() ? TEXT("_") : Result;
} }
FString FlxBlueprintExporter::FormatPinType(UEdGraphPin* Pin) FString FlxBlueprintExporter::FormatPinType(const FEdGraphPinType& PinType)
{ {
if (UObject* SubObj = Pin->PinType.PinSubCategoryObject.Get()) if (UObject* SubObj = PinType.PinSubCategoryObject.Get())
{ {
return SubObj->GetName(); return SubObj->GetName();
} }
FString Type = Pin->PinType.PinCategory.ToString(); FString Type = PinType.PinCategory.ToString();
Type[0] = FChar::ToUpper(Type[0]); Type[0] = FChar::ToUpper(Type[0]);
return Type; return Type;
} }
FString FlxBlueprintExporter::FormatPinType(UEdGraphPin* Pin)
{
return FormatPinType(Pin->PinType);
}
FString FlxBlueprintExporter::FormatNodeBaseName(UEdGraphNode* Node) FString FlxBlueprintExporter::FormatNodeBaseName(UEdGraphNode* Node)
{ {
return SanitizeName(Node->GetNodeTitle(ENodeTitleType::ListView).ToString()); FString Title = Node->GetNodeTitle(ENodeTitleType::ListView).ToString();
Title = FName::NameToDisplayString(*Title, false);
return SanitizeName(Title);
} }
@@ -344,6 +353,25 @@ void FlxBlueprintExporter::EmitNode(UEdGraphNode* Node)
} }
} }
void FlxBlueprintExporter::EmitLocalVariables()
{
for (UEdGraphNode* Node : Graph->Nodes)
{
UK2Node_FunctionEntry* EntryNode = Cast<UK2Node_FunctionEntry>(Node);
if (!EntryNode) continue;
for (const FBPVariableDescription& Var : EntryNode->LocalVariables)
{
FString Default = Var.DefaultValue.IsEmpty() ? TEXT("<default>") : Var.DefaultValue;
Output.Appendf(TEXT("local %s %s = %s\n"),
*FormatPinType(Var.VarType),
*SanitizeName(Var.VarName.ToString()),
*Default);
}
break;
}
}
void FlxBlueprintExporter::EmitGraph() void FlxBlueprintExporter::EmitGraph()
{ {
for (UEdGraphNode* Node : SortedNodes) for (UEdGraphNode* Node : SortedNodes)

View File

@@ -33,6 +33,7 @@ private:
// or struct, for example. But that's OK, we don't // or struct, for example. But that's OK, we don't
// need precise type info, we just need readability. // need precise type info, we just need readability.
// //
static FString FormatPinType(const FEdGraphPinType& PinType);
static FString FormatPinType(UEdGraphPin* Pin); static FString FormatPinType(UEdGraphPin* Pin);
// Get the node base name as a sanitized string. // Get the node base name as a sanitized string.
@@ -101,6 +102,7 @@ private:
void SortNodes(); void SortNodes();
void AssignNodeNames(); void AssignNodeNames();
void EmitNode(UEdGraphNode* Node); void EmitNode(UEdGraphNode* Node);
void EmitLocalVariables();
void EmitGraph(); void EmitGraph();
void EmitNodeList(); void EmitNodeList();