From 218863d077c2acbf38713cc49820f851ea923d59 Mon Sep 17 00:00:00 2001 From: jyelon Date: Sun, 15 Feb 2026 07:13:53 -0500 Subject: [PATCH] Add a blueprint exporter for claude code --- CLAUDE.md | 8 +- Content/Tangibles/TAN_Character.uasset | 4 +- Docs/Blueprint Text Export.md | 50 +++ Source/Integration/BlueprintExporter.cpp | 340 ++++++++++++++++++++ Source/Integration/BlueprintExporter.h | 45 +++ Source/Integration/Integration.cpp | 54 +++- Source/Integration/Integration.h | 12 + Source/Integration/SampleActorComponent.cpp | 34 -- Source/Integration/SampleActorComponent.h | 28 -- Source/Integration/SampleEmptyClass.cpp | 12 - Source/Integration/SampleEmptyClass.h | 15 - Source/Integration/SampleUObject.cpp | 5 - Source/Integration/SampleUObject.h | 17 - 13 files changed, 509 insertions(+), 115 deletions(-) create mode 100644 Docs/Blueprint Text Export.md create mode 100644 Source/Integration/BlueprintExporter.cpp create mode 100644 Source/Integration/BlueprintExporter.h delete mode 100644 Source/Integration/SampleActorComponent.cpp delete mode 100644 Source/Integration/SampleActorComponent.h delete mode 100644 Source/Integration/SampleEmptyClass.cpp delete mode 100644 Source/Integration/SampleEmptyClass.h delete mode 100644 Source/Integration/SampleUObject.cpp delete mode 100644 Source/Integration/SampleUObject.h diff --git a/CLAUDE.md b/CLAUDE.md index 7f427b3a..ce9a5c97 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -86,6 +86,10 @@ Blueprints call into Lua via two mechanisms: Look-at widgets, hotkeys, and menus are built on top of this. The menu system is implemented entirely in "user space" Lua and blueprint code. See `Docs/Displaying Widget Blueprints.md`. +## Blueprint Text Export + +Blueprints are automatically exported to readable text files in `Saved/BlueprintExports/` whenever they are saved in the editor. This lets Claude Code read blueprint logic. See `Docs/Blueprint Text Export.md` for format details. Source: `Source/Integration/BlueprintExporter.h/.cpp` and `Source/Integration/Integration.cpp`. + ## Key Documentation - `Docs/Predictive Reexecution.md` — how the four world models stay in sync @@ -99,9 +103,11 @@ Look-at widgets, hotkeys, and menus are built on top of this. The menu system is - `Docs/Global Variables.md` — different types of global data and their transmission rules - `Docs/Correct Implementation of Blocking Operations and NoPredict.md` — how to handle blocking ops - `Docs/Difference Transmission with Threads.md` — why concurrent diff transmission is hard +- `Docs/Blueprint Text Export.md` — how blueprints are auto-exported to readable text -## Blueprint Coding Conventions +## Coding Conventions +- Do not use static functions in Unreal code. Use class methods or namespace-scoped functions instead. - 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. ## Session Startup diff --git a/Content/Tangibles/TAN_Character.uasset b/Content/Tangibles/TAN_Character.uasset index 6854d190..1cad8bcb 100644 --- a/Content/Tangibles/TAN_Character.uasset +++ b/Content/Tangibles/TAN_Character.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:93de49709b39991ddf52dcf1cbaeb118424a4471089d780c9664a7b57b1d8f73 -size 354038 +oid sha256:109529853d78ad22a2f151ff3f6c1df3f8150e7f7a281c778ca0f3f79328e7ef +size 353527 diff --git a/Docs/Blueprint Text Export.md b/Docs/Blueprint Text Export.md new file mode 100644 index 00000000..5aa911b6 --- /dev/null +++ b/Docs/Blueprint Text Export.md @@ -0,0 +1,50 @@ +# Blueprint Text Export + +Blueprints are stored as binary `.uasset` files that Claude Code cannot read directly. To work around this, a text exporter automatically converts blueprint graphs to readable text files whenever a blueprint is saved in the Unreal editor. + +## How It Works + +The game module (`FlxIntegrationModuleImpl` in `Source/Integration/Integration.cpp`) hooks into `UPackage::PackageSavedWithContextEvent`. When a blueprint is saved, it iterates each `UEdGraph` in the blueprint and runs `FlxBlueprintExporter` on it. The output is written to `Saved/BlueprintExports//.txt`. + +The exporter class (`Source/Integration/BlueprintExporter.h/.cpp`) processes one graph at a time. The constructor runs all passes and the result is available via `GetOutput()`. + +## Output Format + +Each file has two sections: + +**NodeList** maps readable node names to GUIDs: +``` +NodeList: + Event_Tick = 44BAE739C72246DD9E9A72803C3B67CA + Set_Tick_Delta_Seconds = 204486800C0C4906A456A378F9F7ADE4 +``` + +**Graph** shows the flow with pins and connections: +``` +Graph: + + Event_Tick + return Output_Delegate,Delta_Seconds + goto Set_Tick_Delta_Seconds + + Set_Tick_Delta_Seconds + Real Tick_Delta_Seconds = Event_Tick.Delta_Seconds + return Output_Get + goto CallFunctionByName +``` + +- Input data pins: `Type Name = Source` where Source is a `Node.Pin` reference, a literal value, ``, or ``. +- 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). +- String defaults are shown in quotes. +- Variable get nodes are inlined (the variable name appears directly at the point of use). +- Comment nodes appear as `// comment text`. +- Knot (reroute) nodes are followed through transparently. + +## Node Ordering + +Nodes are sorted by a traversal algorithm: find starter nodes (exec output but no exec input), sort them by Y position, then traverse each. The traversal visits a node's inputs first (so data sources appear before their consumers), then emits the node itself, then follows exec outputs. This produces a readable top-down flow. Any unvisited nodes are appended at the end. + +## Node Naming + +Names are derived from `ENodeTitleType::ListView` titles, sanitized to alphanumeric plus underscores. Duplicates get `_2`, `_3`, etc. diff --git a/Source/Integration/BlueprintExporter.cpp b/Source/Integration/BlueprintExporter.cpp new file mode 100644 index 00000000..40cc8924 --- /dev/null +++ b/Source/Integration/BlueprintExporter.cpp @@ -0,0 +1,340 @@ +#if WITH_EDITOR + +#include "BlueprintExporter.h" +#include "Engine/Blueprint.h" +#include "EdGraph/EdGraph.h" +#include "EdGraph/EdGraphNode.h" +#include "EdGraph/EdGraphPin.h" +#include "EdGraphSchema_K2.h" +#include "K2Node_Knot.h" +#include "EdGraphNode_Comment.h" +#include "K2Node_VariableGet.h" +#include "K2Node_CallFunction.h" + +FlxBlueprintExporter::FlxBlueprintExporter(UEdGraph* InGraph) + : Graph(InGraph) +{ + SortNodes(); + AssignNodeNames(); + EmitNodeList(); + EmitGraph(); +} + +void FlxBlueprintExporter::AssignNodeNames() +{ + TMap NextIndex; + + for (UEdGraphNode* Node : SortedNodes) + { + FString Base = SanitizeName(Node->GetNodeTitle(ENodeTitleType::ListView).ToString()); + int32& Idx = NextIndex.FindOrAdd(Base, 0); + FString Name = (Idx == 0) ? Base : FString::Printf(TEXT("%s_%d"), *Base, Idx + 1); + NodeNames.Add(Node, Name); + Idx++; + } +} + +void FlxBlueprintExporter::Traverse(UEdGraphNode* Node) +{ + if (Visited.Contains(Node)) return; + Visited.Add(Node); + + // First, traverse input nodes + for (UEdGraphPin* Pin : Node->Pins) + { + if (Pin->Direction != EGPD_Input) continue; + for (UEdGraphPin* LinkedPin : Pin->LinkedTo) + { + Traverse(LinkedPin->GetOwningNode()); + } + } + + // Add this node to the sorted list. + SortedNodes.Add(Node); + + // Then, traverse exec output nodes only. + // Data outputs are not followed — data nodes get pulled in + // through their consumers' input traversal. + for (UEdGraphPin* Pin : Node->Pins) + { + if (Pin->Direction != EGPD_Output) continue; + if (Pin->PinType.PinCategory != UEdGraphSchema_K2::PC_Exec) continue; + for (UEdGraphPin* LinkedPin : Pin->LinkedTo) + { + Traverse(LinkedPin->GetOwningNode()); + } + } +} + +bool FlxBlueprintExporter::HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction) +{ + for (UEdGraphPin* Pin : Node->Pins) + { + if (Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) + { + if (Pin->Direction == Direction) return true; + } + } + return false; +} + +void FlxBlueprintExporter::SortNodes() +{ + // Find starter nodes: have exec output but no exec input. + TArray Starters; + for (UEdGraphNode* Node : Graph->Nodes) + { + if (HasExecPin(Node, EGPD_Output) && !HasExecPin(Node, EGPD_Input)) + { + Starters.Add(Node); + } + } + + // Sort starters by Y position. + Starters.Sort([](const UEdGraphNode& A, const UEdGraphNode& B) + { + return A.NodePosY < B.NodePosY; + }); + + // Traverse from each starter. + for (UEdGraphNode* Starter : Starters) + { + Traverse(Starter); + } + + // Traverse all nodes. + for (UEdGraphNode* Node : Graph->Nodes) + { + Traverse(Node); + } +} + +void FlxBlueprintExporter::EmitNodeList() +{ + Output.Appendf(TEXT("NodeList:\n")); + for (UEdGraphNode* Node : SortedNodes) + { + if (Node->IsA()) continue; + if (Node->IsA()) continue; + if (Node->IsA()) continue; + Output.Appendf(TEXT(" %s = %s\n"), + *NodeNames[Node], *Node->NodeGuid.ToString()); + } +} + +FString FlxBlueprintExporter::GetPinDisplayName(UEdGraphPin *Pin) +{ + FString Result = Pin->GetOwningNode()->GetPinDisplayName(Pin).ToString(); + if (!Result.IsEmpty()) return Result; + return Pin->PinName.ToString(); +} + +UEdGraphPin* FlxBlueprintExporter::FindFirstPin(UEdGraphNode* Node, EEdGraphPinDirection Direction) +{ + for (UEdGraphPin* Pin : Node->Pins) + { + if (Pin->Direction == Direction) return Pin; + } + return nullptr; +} + +UEdGraphPin* FlxBlueprintExporter::GetLinkedTo(UEdGraphPin* Pin) +{ + while (true) + { + if (Pin == nullptr) return nullptr; + if (Pin->LinkedTo.IsEmpty()) return nullptr; + UEdGraphPin *LinkedTo = Pin->LinkedTo[0]; + if (!LinkedTo->GetOwningNode()->IsA()) return LinkedTo; + Pin = FindFirstPin(LinkedTo->GetOwningNode(), Pin->Direction); + } +} + +FString FlxBlueprintExporter::FormatPinType(UEdGraphPin* Pin) +{ + if (UObject* SubObj = Pin->PinType.PinSubCategoryObject.Get()) + { + return SubObj->GetName(); + } + FString Type = Pin->PinType.PinCategory.ToString(); + Type[0] = FChar::ToUpper(Type[0]); + return Type; +} + +FString FlxBlueprintExporter::FormatPinSource(UEdGraphPin* Pin) +{ + // If connected, show source node.pin + UEdGraphPin* LinkedTo = GetLinkedTo(Pin); + if (LinkedTo != nullptr) + { + UEdGraphNode* LinkedToNode = LinkedTo->GetOwningNode(); + + // For variable get nodes, just show the variable name. + if (UK2Node_VariableGet* VarGet = Cast(LinkedToNode)) + return SanitizeName(VarGet->GetVarNameString()); + + FString PinLabel = SanitizeName(GetPinDisplayName(LinkedTo)); + FString* Name = NodeNames.Find(LinkedToNode); + return FString::Printf(TEXT("%s.%s"), **Name, *PinLabel); + } + + // String pins: always show in quotes (even if empty). + FName Category = Pin->PinType.PinCategory; + if (Category == UEdGraphSchema_K2::PC_String || + Category == UEdGraphSchema_K2::PC_Name || + Category == UEdGraphSchema_K2::PC_Text) + { + return FString::Printf(TEXT("\"%s\""), *Pin->DefaultValue); + } + + // If has a non-empty default, show it. + if (!Pin->DefaultValue.IsEmpty()) + { + return Pin->DefaultValue; + } + + if (Pin->DefaultObject) + { + return Pin->DefaultObject->GetName(); + } + + if (!Pin->DefaultTextValue.IsEmpty()) + { + return FString::Printf(TEXT("\"%s\""), *Pin->DefaultTextValue.ToString()); + } + + if (IsDefaultToSelf(Pin)) + { + return TEXT(""); + } + else + { + return TEXT(""); + } +} + +void FlxBlueprintExporter::EmitNode(UEdGraphNode* Node) +{ + if (Node->IsA()) + { + Output.Appendf(TEXT("\n // %s\n"), *Node->NodeComment); + return; + } + + if (Node->IsA()) + return; + + Output.Appendf(TEXT("\n %s\n"), *NodeNames[Node]); + + // Emit input data pins. + for (UEdGraphPin* Pin : Node->Pins) + { + if (Pin->Direction != EGPD_Input) continue; + if (Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) continue; + if (Pin->bHidden) continue; + + Output.Appendf(TEXT(" %s %s = %s\n"), + *FormatPinType(Pin), + *SanitizeName(GetPinDisplayName(Pin)), + *FormatPinSource(Pin)); + } + + // Emit output data pins as a return line. + FString ReturnPins; + for (UEdGraphPin* Pin : Node->Pins) + { + if (Pin->Direction != EGPD_Output) continue; + if (Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec) continue; + if (Pin->bHidden) continue; + if (!ReturnPins.IsEmpty()) ReturnPins += TEXT(","); + ReturnPins += SanitizeName(GetPinDisplayName(Pin)); + } + if (!ReturnPins.IsEmpty()) + Output.Appendf(TEXT(" return %s\n"), *ReturnPins); + + // Detect output exec pin patterns. + int32 ExecOutCount = 0; + bool HasElsePin = false; + for (UEdGraphPin* Pin : Node->Pins) + { + if (Pin->Direction != EGPD_Output) continue; + if (Pin->PinType.PinCategory != UEdGraphSchema_K2::PC_Exec) continue; + ExecOutCount++; + if (Pin->PinName == TEXT("Else")) + HasElsePin = true; + } + + // Emit output exec pins as goto statements. + for (UEdGraphPin* Pin : Node->Pins) + { + if (Pin->Direction != EGPD_Output) continue; + if (Pin->PinType.PinCategory != UEdGraphSchema_K2::PC_Exec) continue; + UEdGraphPin* LinkedTo = GetLinkedTo(Pin); + if (!LinkedTo) continue; + + FString* TargetName = NodeNames.Find(LinkedTo->GetOwningNode()); + FString Target = TargetName ? *TargetName : TEXT("?"); + + if (ExecOutCount == 1) + Output.Appendf(TEXT(" goto %s\n"), *Target); + else if (HasElsePin) + Output.Appendf(TEXT(" %s goto %s\n"), *Pin->PinName.ToString().ToLower(), *Target); + else + Output.Appendf(TEXT(" goto %s if %s\n"), *Target, *Pin->PinName.ToString()); + } +} + +void FlxBlueprintExporter::EmitGraph() +{ + Output.Appendf(TEXT("\nGraph:\n")); + for (UEdGraphNode* Node : SortedNodes) + { + if (Node->IsA()) continue; + EmitNode(Node); + } +} + +bool FlxBlueprintExporter::IsDefaultToSelf(UEdGraphPin* Pin) +{ + // The engine's own IsSelfPin check. + if (Pin->PinName == UEdGraphSchema_K2::PN_Self) + return true; + + // Check if the owning node is a function call with DefaultToSelf metadata naming this pin. + UK2Node_CallFunction* CallNode = Cast(Pin->GetOwningNode()); + if (!CallNode) return false; + + UFunction* Function = CallNode->GetTargetFunction(); + if (!Function) return false; + + const FString& DefaultToSelfPinName = Function->GetMetaData(FBlueprintMetadata::MD_DefaultToSelf); + return Pin->PinName.ToString() == DefaultToSelfPinName; +} + +FString FlxBlueprintExporter::SanitizeName(const FString& Title) +{ + FString Result; + bool PrevWasUnderscore = true; // suppress leading underscore + for (TCHAR Ch : Title) + { + if (FChar::IsAlnum(Ch)) + { + Result += Ch; + PrevWasUnderscore = false; + } + else if (!PrevWasUnderscore) + { + Result += TEXT('_'); + PrevWasUnderscore = true; + } + } + // Trim trailing underscore + if (Result.Len() > 0 && Result[Result.Len() - 1] == TEXT('_')) + { + Result.LeftChopInline(1); + } + return Result.IsEmpty() ? TEXT("_") : Result; +} + + +#endif diff --git a/Source/Integration/BlueprintExporter.h b/Source/Integration/BlueprintExporter.h new file mode 100644 index 00000000..98539d79 --- /dev/null +++ b/Source/Integration/BlueprintExporter.h @@ -0,0 +1,45 @@ +#pragma once + +#if WITH_EDITOR + +#include "CoreMinimal.h" + +class UBlueprint; +class UEdGraph; +class UEdGraphNode; + +class FlxBlueprintExporter +{ +public: + FlxBlueprintExporter(UEdGraph* InGraph); + + const FString GetOutput() { return Output.ToString(); } + +private: + void SortNodes(); + void AssignNodeNames(); + void EmitNodeList(); + void EmitGraph(); + void EmitNode(UEdGraphNode* Node); + void Traverse(UEdGraphNode* Node); + bool HasExecPin(UEdGraphNode* Node, EEdGraphPinDirection Direction); + UEdGraphPin* FindFirstPin(UEdGraphNode* Node, EEdGraphPinDirection Direction); + bool IsDefaultToSelf(UEdGraphPin* Pin); + FString SanitizeName(const FString& Title); + FString FormatPinType(UEdGraphPin* Pin); + FString FormatPinSource(UEdGraphPin* Pin); + UEdGraphPin* GetLinkedTo(UEdGraphPin *Pin); + FString GetPinDisplayName(UEdGraphPin *Pin); + + UEdGraph* Graph; + + // Data populated by passes. + TMap NodeNames; + TArray SortedNodes; + TSet Visited; + + // Output buffer. + TStringBuilder<4096> Output; +}; + +#endif diff --git a/Source/Integration/Integration.cpp b/Source/Integration/Integration.cpp index 8b2306bf..62e417af 100644 --- a/Source/Integration/Integration.cpp +++ b/Source/Integration/Integration.cpp @@ -3,4 +3,56 @@ #include "Integration.h" #include "Modules/ModuleManager.h" -IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Integration, "Integration" ); +#if WITH_EDITOR +#include "Engine/Blueprint.h" +#include "UObject/SavePackage.h" +#include "UObject/ObjectSaveContext.h" +#include "EdGraph/EdGraph.h" +#include "BlueprintExporter.h" +#include "Misc/FileHelper.h" +#endif + +IMPLEMENT_PRIMARY_GAME_MODULE(FlxIntegrationModuleImpl, Integration, "Integration"); + +void FlxIntegrationModuleImpl::StartupModule() +{ +#if WITH_EDITOR + OnAssetSavedHandle = UPackage::PackageSavedWithContextEvent.AddRaw( + this, &FlxIntegrationModuleImpl::OnAssetSaved); +#endif +} + +void FlxIntegrationModuleImpl::ShutdownModule() +{ +#if WITH_EDITOR + UPackage::PackageSavedWithContextEvent.Remove(OnAssetSavedHandle); +#endif +} + +#if WITH_EDITOR +void FlxIntegrationModuleImpl::OnAssetSaved(const FString& PackageFilename, UPackage* Package, FObjectPostSaveContext Context) +{ + if (!Package) return; + + ForEachObjectWithPackage(Package, [&](UObject* Object) + { + if (UBlueprint* BP = Cast(Object)) + { + FString BPDir = FPaths::ProjectDir() / TEXT("Saved") / TEXT("BlueprintExports") / BP->GetName(); + + TArray AllGraphs; + BP->GetAllGraphs(AllGraphs); + + for (UEdGraph* Graph : AllGraphs) + { + FlxBlueprintExporter Exporter(Graph); + + FString FilePath = BPDir / Graph->GetName() + TEXT(".txt"); + FFileHelper::SaveStringToFile(Exporter.GetOutput(), *FilePath); + UE_LOG(LogTemp, Warning, TEXT("Blueprint export: %s"), *FilePath); + } + } + return true; + }); +} +#endif diff --git a/Source/Integration/Integration.h b/Source/Integration/Integration.h index 677c8e25..3855be13 100644 --- a/Source/Integration/Integration.h +++ b/Source/Integration/Integration.h @@ -4,3 +4,15 @@ #include "CoreMinimal.h" +class FlxIntegrationModuleImpl : public IModuleInterface +{ +public: + virtual void StartupModule() override; + virtual void ShutdownModule() override; + +private: +#if WITH_EDITOR + void OnAssetSaved(const FString& PackageFilename, UPackage* Package, FObjectPostSaveContext Context); + FDelegateHandle OnAssetSavedHandle; +#endif +}; diff --git a/Source/Integration/SampleActorComponent.cpp b/Source/Integration/SampleActorComponent.cpp deleted file mode 100644 index b5142a32..00000000 --- a/Source/Integration/SampleActorComponent.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - - -#include "SampleActorComponent.h" - -// Sets default values for this component's properties -USampleActorComponent::USampleActorComponent() -{ - // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features - // off to improve performance if you don't need them. - PrimaryComponentTick.bCanEverTick = true; - - // ... -} - - -// Called when the game starts -void USampleActorComponent::BeginPlay() -{ - Super::BeginPlay(); - - // ... - -} - - -// Called every frame -void USampleActorComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) -{ - Super::TickComponent(DeltaTime, TickType, ThisTickFunction); - - // ... -} - diff --git a/Source/Integration/SampleActorComponent.h b/Source/Integration/SampleActorComponent.h deleted file mode 100644 index fe00ca06..00000000 --- a/Source/Integration/SampleActorComponent.h +++ /dev/null @@ -1,28 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "Components/ActorComponent.h" -#include "SampleActorComponent.generated.h" - - -UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) -class INTEGRATION_API USampleActorComponent : public UActorComponent -{ - GENERATED_BODY() - -public: - // Sets default values for this component's properties - USampleActorComponent(); - -protected: - // Called when the game starts - virtual void BeginPlay() override; - -public: - // Called every frame - virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; - - -}; diff --git a/Source/Integration/SampleEmptyClass.cpp b/Source/Integration/SampleEmptyClass.cpp deleted file mode 100644 index dfa0276e..00000000 --- a/Source/Integration/SampleEmptyClass.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - - -#include "SampleEmptyClass.h" - -SampleEmptyClass::SampleEmptyClass() -{ -} - -SampleEmptyClass::~SampleEmptyClass() -{ -} diff --git a/Source/Integration/SampleEmptyClass.h b/Source/Integration/SampleEmptyClass.h deleted file mode 100644 index f61168a6..00000000 --- a/Source/Integration/SampleEmptyClass.h +++ /dev/null @@ -1,15 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" - -/** - * - */ -class INTEGRATION_API SampleEmptyClass -{ -public: - SampleEmptyClass(); - ~SampleEmptyClass(); -}; diff --git a/Source/Integration/SampleUObject.cpp b/Source/Integration/SampleUObject.cpp deleted file mode 100644 index 02ec96b9..00000000 --- a/Source/Integration/SampleUObject.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - - -#include "SampleUObject.h" - diff --git a/Source/Integration/SampleUObject.h b/Source/Integration/SampleUObject.h deleted file mode 100644 index abd28fba..00000000 --- a/Source/Integration/SampleUObject.h +++ /dev/null @@ -1,17 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "UObject/NoExportTypes.h" -#include "SampleUObject.generated.h" - -/** - * - */ -UCLASS() -class INTEGRATION_API USampleUObject : public UObject -{ - GENERATED_BODY() - -};