Compare commits

..

2 Commits

Author SHA1 Message Date
1b0d96934f Readme updates 2026-06-01 20:53:02 -04:00
cc34e36cd2 A small refactor in UEWingman, for readability 2026-06-01 20:53:02 -04:00
36 changed files with 256 additions and 249 deletions

View File

@@ -1,12 +1,14 @@
# UE Wingman # UE Wingman
UE Wingman is a tool that allows an AI to control the unreal ue-wingman is a command-line program that allows an AI
editor. When you're using it, it feels like the AI is right to use the unreal editor. The AI can use this command
there looking at the editor with you. You'll be able to to do things like:
watch as it creates graph nodes and wires them together,
you'll see it add components to your blueprints, you'll see * Create blueprints
it design widget hierarchies for you, and you'll see it write * Wire up graph nodes
shaders for your materials. * Edit parameters in the details panel
* Manipulate actor components
* Build widget hierarchies
The tool is not complete, not by a long shot. There are The tool is not complete, not by a long shot. There are
tons of Unreal Editor functions that the AI just can't tons of Unreal Editor functions that the AI just can't
@@ -14,60 +16,152 @@ access yet. Even so, I think it's useful: it has pretty
comprehensive support to allow the AI agent to help create comprehensive support to allow the AI agent to help create
blueprints, widget blueprints, and materials. blueprints, widget blueprints, and materials.
## How Does it Work? ## Example Commands
This tool adds a command line interpreter plugin to the Unreal
Editor. You can type commands, and the plugin in the editor
will execute them.
The AI can print out a graph in a text form, so it can read
it. Here's the dump of a simple event graph that doesn't
have much in it yet:
``` ```
$ ue-wingman Graph_Dump /Game/Testing/BP_Test,graph:EventGraph $ ue-wingman.py Graph_Dump /Game/Testing/BP_Test,graph:EventGraph
node K2Node_Event_0: Event BeginPlay node K2Node_Event_0: Event BeginPlay
output-pins OutputDelegate output-pins OutputDelegate
node K2Node_Event_2: Event Tick node K2Node_Event_2: Event Tick
output-pins OutputDelegate, DeltaSeconds output-pins OutputDelegate, DeltaSeconds
``` ```
The ue-wingman command has tons of subcommands: Graph_Dump, Here, the AI asks: what kinds of graph nodes can I add to the
GraphNode_Add, GraphPin_Connect, BlueprintComponent_Add, event graph, that contain the words "Hit Result Under Cursor":
Widget_Add, and so forth. Using these commands, it's
possible to examine and modify blueprints, widgets, and
materials.
But, of course, these commands aren't really intended for humans. ```
They're intended for an AI agent. $ ue-wingman.py GraphNode_SearchTypes /game/testing/bp_test,graph:EventGraph 50 "Hit Result under Cursor"
## Why Choose this Particular Unreal AI Plugin? === Hit Result under Cursor ===
There are a *lot* of Unreal Engine AI plugins out there. Some of PlayerController|Game|Player|GetHitResultUnderCursorForObjects
them are, shall we say, not carefully engineered. I'm a PlayerController|Game|Player|GetHitResultUnderCursorByChannel
reasonably skilled software engineer and I've designed ```
this plugin to be robust and capable of sustained development.
This plugin is also designed to be as broadly general as Next, the AI adds a node to the event graph:
possible. I've seen plugins that claim "can create 22 different
kinds of graph nodes!" This makes me ask: why not just
provide the *entire catalog* of all possible graph nodes?
I've seen plugins claim "you can edit 15 different material
expression properties!" Why not provide access to *all*
editable material expression properties? I've tried to make
every tool in this plugin as capable as possible, with as few
limits as possible.
Some of the MCPs out there expose the entire Unreal API to ```
the AI agent. That is not entirely safe. AI agents will $ ue-wingman.py GraphNode_Add /game/testing/bp_test,graph:EventGraph "PlayerController|Game|Player|GetHitResultUnderCursorByChannel" 100 100
very often carelessly call API functions they shouldn't, Spawned: PlayerController|Game|Player|GetHitResultUnderCursorByChannel
crashing your editor or corrupting your assets. All the node K2Node_CallFunction_0: Get Hit Result Under Cursor by Channel
commands supported by this MCP are error-checked. It is pos 96, 96
intended that they won't let the AI do something that would input-pin PlayerController self = <default>
crash your editor. input-pin ETraceTypeQuery TraceChannel = TraceTypeQuery1
input-pin bool bTraceComplex = TRUE
output-pins HitResult HitResult, bool ReturnValue
```
This MCP is very extensible. Adding a new command requires The AI changes the value of 'bTraceComplex' on the hit-result node:
a relatively small amount of code. I'm hoping some others
in the community will eventually start contributing new ```
commands. $ ue-wingman.py GraphNode_SetDefault /game/testing/bp_test,graph:EventGraph,node:K2Node_CallFunction_0 bTraceComplex False
Done.
```
The AI can view the details panel for almost any object.
Here's a partial dump from an enhanced input action:
```
$ ue-wingman.py Details_Dump /game/luprex/InputActions/IA_Menu
Action:
editable bool bTriggerWhenPaused = False
editable bool bReserveAllMappings = False
editable EInputActionValueType ValueType = Boolean
editable EInputActionAccumulationBehavior AccumulationBehavior = TakeHighestAbsoluteValue
editable Array<InputTrigger> Triggers =
...
```
## List of Current Commands, Excluding Asset Creation Commands
```
ActorComponent_Add Blueprint Class Component Parent
ActorComponent_Remove Component
ActorComponent_Reparent Component Parent
Asset_Backup Asset
Asset_ContentBrowse Path
Asset_Delete Asset Force
Asset_FindReferences Asset
Asset_Rename Asset NewPath
Asset_Restore Asset
Asset_Search Query Type Limit
Blueprint_AddInterface Blueprint Interface
Blueprint_Compile Blueprint
Blueprint_Dump Blueprint
Blueprint_RemoveInterface Blueprint Interface PreserveFunctions
Blueprint_Reparent Blueprint Parent
BlueprintGraph_Add Blueprint Graph GraphType [Variables...]
BlueprintGraph_Remove Graph
BlueprintOverride_Add Blueprint Function
BlueprintOverride_ShowMenu Blueprint
Create_MaterialInstance Path ParentMaterial
Details_Dump Object
Details_Get Object Property
Details_Set Object Property Value
Documentation_Command Command
Documentation_Commands
Documentation_CreateAssets Query Verbose
Documentation_Manual
Documentation_Section Section
Editor_ListOpenAssets
Editor_OpenAsset Asset
EventDispatcher_Add Blueprint Dispatcher [Variables...]
EventDispatcher_Remove Blueprint Dispatcher
Graph_Dump Graph Details
GraphNode_Add Graph Type PosX PosY
GraphNode_ChooseMenu Node Item
GraphNode_Dump Node Details
GraphNode_GetComment Node
GraphNode_Remove Node
GraphNode_Rename Node Name
GraphNode_SearchTypes Graph MaxResults [Queries...]
GraphNode_SetComment Node Comment
GraphNode_SetDefault Graph Node Name Value
GraphNode_SetPosition Graph Node X Y
GraphNode_ShowMenu Node
GraphPin_Connect Graph [SourcePin_TargetPin...]
GraphPin_Disconnect Graph [Pins...]
Material_Compile Material
Material_DumpParameters Material
MaterialInstance_ClearParameter MaterialInstance Parameter
MaterialInstance_DumpParameters MaterialInstance
MaterialInstance_SetParameter MaterialInstance Parameter Value
SysInfo_Factories
SysInfo_PackageContents Package
TypeName_Search Query Limit
Variables_Add Object [Variables...]
Variables_Dump Object
Variables_Modify Object [Variables...]
Variables_Remove Object [Variables...]
Widget_Add Blueprint Type Name Parent IsVariable
Widget_Remove Widget
Widget_Reparent Widget Parent
Widget_SearchTypes MaxResults [Queries...]
```
## Installation ## Installation
@@ -75,68 +169,60 @@ There are two parts to UE Wingman:
* The Unreal Plugin, which does 99% of the work. * The Unreal Plugin, which does 99% of the work.
* The python program "ue-wingman.py" * The command-line program "ue-wingman.py"
The python program is actually less than 100 lines of code: The command-line program is actually less than 100 lines of
all it does is package up its command line arguments, send python. All it does is package up its command line
them to the plugin, and let the plugin do the work. Then it arguments, send them to the plugin, and let the plugin do
prints the output. the work. Then it prints the output. To install it,
just copy it into your PATH. I like to remove the ".py"
extension, but that's optional.
If you build Unreal from source, the best way to install the Currently, the only way to install the plugin is to build
plugin is to drop the entire UEWingman source folder into it from source. I just don't have to the time to make
your Plugins folder. Then do a build. Restart the editor, and a binary distribution. Building from source is simple:
go into your plugins configuration. Enable the UE Wingman just drop the entire plugin folder into one of two places:
plugin. You're done.
If you don't build from source, then unfortunately, you're * Option 1: UnrealEngine/Engine/Plugins/UEWingman
out of luck. Precompiled plugins must be built for every * Option 2: YourGame/Plugins/UEWingman
different OS, for every different engine version. I just
don't have the means to do that right now.
After installing the plugin, you need to install the two Then, do a build using unreal build tool. Restart the
python programs. They are both short and simple: all they editor, and go into your plugins configuration. Enable the
do is establish a network connection to the plugin, and then UE Wingman plugin. You're done.
send the command you typed. They require python 3.6 or later,
and no other dependencies.
To install the human version, ue-wingman.py, just drop it into ## The Built-in Documentation
a folder on your PATH.
## The "User Manual" The tool has a built-in user manual, which you can access
by typing this:
You might be interested in seeing the "user manual" for the
plugin. To get that, you type this:
``` ```
$ ue-wingman.py Documentation_Manual $ ue-wingman.py Documentation_Manual
``` ```
Of course, you're not the intended user: your AI agent is. Alternately, you can just type ue-wingman with no arguments.
This manual isn't really intended for humans, it's meant
for the AI agent, so it's a little dense.
You should put a note into your agent's system prompt to You should put a note into your agent's system prompt to
let it know about the ue-wingman.py command, and to let let it know about the ue-wingman command, and to let
it know that it can type ue-wingman.py Documentation_Manual. it know that it can type ue-wingman.py Documentation_Manual.
This in turn will tell your agent about this command:
The manual mentions several other commands, including
these, which emit documentation for the built-in subcommands:
``` ```
$ ue-wingman.py Documentation_Commands $ ue-wingman.py Documentation_Commands
$ ue-wingman.py Documentation_Command
``` ```
Using these commands, you can learn more about what this Using these commands, you can learn more about what this
plugin can do. plugin can do.
## Fun things to Try
I really started enjoying this plugin when I asked my agent
to make me a "cool looking material, something psychedelic
and weird." It made a neat kaleidoscope thing. I then
asked it to make me an animated rendering of the mandelbrot
set. It's fun to watch it do things like that.
## History and Credits ## History and Credits
When I myself needed an MCP for unreal development, I did a When I myself needed a tool like this, I did a survey of the
survey of the plugins out there. I ended up choosing a plugins out there. I ended up choosing a plugin called
plugin called "Blueprint MCP" by David Gundry: "Blueprint MCP" by David Gundry:
<https://github.com/mirno-ehf/ue5-mcp> <https://github.com/mirno-ehf/ue5-mcp>
@@ -146,16 +232,16 @@ pretty much the whole thing. So this whole project is actually
a fork of Blueprint MCP. There's very little of the original a fork of Blueprint MCP. There's very little of the original
code remaining. However, you will find snippets here and there. code remaining. However, you will find snippets here and there.
Even though I ended up rewriting most of the code, it really Even though I ended up rewriting essentially all of the
was useful to have a functioning starting point. It meant I code, it really was useful to have a functioning starting
could improve one thing at a time, without having to try to point. It meant I could improve one thing at a time,
get everything working all at once. So I'm quite grateful without having to try to get everything working all at once.
to David Gundry and his work. So I'm quite grateful to David Gundry and his work.
## Software License ## Software License
UE Wingman is licensed under the MIT license, a copy of which UE Wingman is licensed under the MIT license, a copy of which
is enclosed. Its predecessor (of which it is a fork) was also is enclosed. Its predecessor Blueprint MCP was also
under the MIT license, so everything works out. under the MIT license, so everything works out.

View File

@@ -19,7 +19,7 @@ class UWing_ActorComponent_Remove : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to the component (e.g. '/Game/MyBP,component:MyComp')")) UPROPERTY(EditAnywhere, meta=(Description="Path to the component (e.g. '/Game/MyBP,component:MyComp')"))
FString Component; FString ComponentPath;
virtual void Register() override virtual void Register() override
{ {
@@ -29,7 +29,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UWingComponentRef* CompRef = F.Walk(Component).Cast<UWingComponentRef>(); UWingComponentRef* CompRef = F.Walk(ComponentPath).Cast<UWingComponentRef>();
if (!CompRef) return; if (!CompRef) return;
if (!UWingComponent::DeleteComponent(CompRef, WingOut::Stdout)) return; if (!UWingComponent::DeleteComponent(CompRef, WingOut::Stdout)) return;

View File

@@ -21,7 +21,7 @@ class UWing_ActorComponent_Reparent : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to the component (e.g. '/Game/MyBP,component:MyComp')")) UPROPERTY(EditAnywhere, meta=(Description="Path to the component (e.g. '/Game/MyBP,component:MyComp')"))
FString Component; FString ComponentPath;
UPROPERTY(EditAnywhere, meta=(Description="New parent component name.")) UPROPERTY(EditAnywhere, meta=(Description="New parent component name."))
FString Parent; FString Parent;
@@ -34,7 +34,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UWingComponentRef* CompRef = F.Walk(Component).Cast<UWingComponentRef>(); UWingComponentRef* CompRef = F.Walk(ComponentPath).Cast<UWingComponentRef>();
if (!CompRef) return; if (!CompRef) return;
// Find the new parent among all components (if specified) // Find the new parent among all components (if specified)

View File

@@ -24,7 +24,7 @@ class UWing_BlueprintGraph_Add : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Blueprint name or package path")) UPROPERTY(EditAnywhere, meta=(Description="Blueprint name or package path"))
FString Blueprint; FString BlueprintPath;
UPROPERTY(EditAnywhere, meta=(Description="Name for the new graph")) UPROPERTY(EditAnywhere, meta=(Description="Name for the new graph"))
FString Graph; FString Graph;
@@ -51,7 +51,7 @@ public:
} }
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>(); UBlueprint* BP = F.Walk(BlueprintPath).Cast<UBlueprint>();
if (!BP) return; if (!BP) return;
// Check that this graph type is valid for this blueprint type // Check that this graph type is valid for this blueprint type

View File

@@ -22,7 +22,7 @@ class UWing_BlueprintGraph_Remove : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to the graph, e.g. /Game/MyBP,graph:MyFunction")) UPROPERTY(EditAnywhere, meta=(Description="Path to the graph, e.g. /Game/MyBP,graph:MyFunction"))
FString Graph; FString GraphPath;
virtual void Register() override virtual void Register() override
{ {
@@ -32,7 +32,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraph* FoundGraph = F.Walk(Graph).Cast<UEdGraph>(); UEdGraph* FoundGraph = F.Walk(GraphPath).Cast<UEdGraph>();
if (!FoundGraph) return; if (!FoundGraph) return;
UBlueprint* BP = FBlueprintEditorUtils::FindBlueprintForGraph(FoundGraph); UBlueprint* BP = FBlueprintEditorUtils::FindBlueprintForGraph(FoundGraph);

View File

@@ -22,7 +22,7 @@ class UWing_BlueprintOverride_Add : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Blueprint path")) UPROPERTY(EditAnywhere, meta=(Description="Blueprint path"))
FString Blueprint; FString BlueprintPath;
UPROPERTY(EditAnywhere, meta=(Description="Function to override, in Class|Function format")) UPROPERTY(EditAnywhere, meta=(Description="Function to override, in Class|Function format"))
FString Function; FString Function;
@@ -36,7 +36,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>(); UBlueprint* BP = F.Walk(BlueprintPath).Cast<UBlueprint>();
if (!BP) return; if (!BP) return;
// Find the function by matching against the menu string format (Class|Function) // Find the function by matching against the menu string format (Class|Function)

View File

@@ -21,7 +21,7 @@ class UWing_BlueprintOverride_ShowMenu : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Blueprint path")) UPROPERTY(EditAnywhere, meta=(Description="Blueprint path"))
FString Blueprint; FString BlueprintPath;
virtual void Register() override virtual void Register() override
{ {
@@ -32,7 +32,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>(); UBlueprint* BP = F.Walk(BlueprintPath).Cast<UBlueprint>();
if (!BP) return; if (!BP) return;
TArray<UFunction*> Results = WingUtils::GetOverridableFunctions(BP); TArray<UFunction*> Results = WingUtils::GetOverridableFunctions(BP);

View File

@@ -30,7 +30,7 @@ class UWing_Blueprint_Dump : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Blueprint path")) UPROPERTY(EditAnywhere, meta=(Description="Blueprint path"))
FString Blueprint; FString BlueprintPath;
virtual void Register() override virtual void Register() override
{ {
@@ -41,7 +41,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>(); UBlueprint* BP = F.Walk(BlueprintPath).Cast<UBlueprint>();
if (!BP) return; if (!BP) return;
// Header // Header

View File

@@ -14,7 +14,7 @@ class UWing_Details_Dump : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target object")) UPROPERTY(EditAnywhere, meta=(Description="Target object"))
FString Object; FString ObjectPath;
virtual void Register() override virtual void Register() override
{ {
@@ -25,7 +25,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UObject* Target = F.Walk(Object).Cast<UObject>(); UObject* Target = F.Walk(ObjectPath).Cast<UObject>();
if (!Target) return; if (!Target) return;
TArray<FWingProperty> Props = FWingProperty::GetDetails(Target, false); TArray<FWingProperty> Props = FWingProperty::GetDetails(Target, false);

View File

@@ -15,7 +15,7 @@ class UWing_Details_Get : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target object")) UPROPERTY(EditAnywhere, meta=(Description="Target object"))
FString Object; FString ObjectPath;
UPROPERTY(EditAnywhere, meta=(Description="Property name")) UPROPERTY(EditAnywhere, meta=(Description="Property name"))
FString Property; FString Property;
@@ -29,7 +29,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UObject* Obj = F.Walk(Object).Cast<UObject>(); UObject* Obj = F.Walk(ObjectPath).Cast<UObject>();
if (!Obj) return; if (!Obj) return;
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, false); TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, false);

View File

@@ -15,7 +15,7 @@ class UWing_Details_Set : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target object")) UPROPERTY(EditAnywhere, meta=(Description="Target object"))
FString Object; FString ObjectPath;
UPROPERTY(EditAnywhere, meta=(Description="Property name")) UPROPERTY(EditAnywhere, meta=(Description="Property name"))
FString Property; FString Property;
@@ -32,7 +32,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UObject* Obj = F.Walk(Object).Cast<UObject>(); UObject* Obj = F.Walk(ObjectPath).Cast<UObject>();
if (!Obj) return; if (!Obj) return;
TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, true); TArray<FWingProperty> Props = FWingProperty::GetDetails(Obj, true);

View File

@@ -20,7 +20,7 @@ class UWing_Editor_OpenAsset : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Asset to open")) UPROPERTY(EditAnywhere, meta=(Description="Asset to open"))
FString Asset; FString AssetPath;
virtual void Register() override virtual void Register() override
{ {
@@ -30,7 +30,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UObject* Obj = F.Walk(Asset).Cast<UObject>(); UObject* Obj = F.Walk(AssetPath).Cast<UObject>();
if (!Obj) return; if (!Obj) return;
UAssetEditorSubsystem* Sub = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>(); UAssetEditorSubsystem* Sub = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>();

View File

@@ -23,7 +23,7 @@ class UWing_EventDispatcher_Add : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Blueprint name or package path")) UPROPERTY(EditAnywhere, meta=(Description="Blueprint name or package path"))
FString Blueprint; FString BlueprintPath;
UPROPERTY(EditAnywhere, meta=(Description="Name of the new event dispatcher")) UPROPERTY(EditAnywhere, meta=(Description="Name of the new event dispatcher"))
FString Dispatcher; FString Dispatcher;
@@ -42,7 +42,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>(); UBlueprint* BP = F.Walk(BlueprintPath).Cast<UBlueprint>();
if (!BP) return; if (!BP) return;
// Check for valid proposed name // Check for valid proposed name

View File

@@ -21,7 +21,7 @@ class UWing_EventDispatcher_Remove : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Blueprint name or package path")) UPROPERTY(EditAnywhere, meta=(Description="Blueprint name or package path"))
FString Blueprint; FString BlueprintPath;
UPROPERTY(EditAnywhere, meta=(Description="Name of the event dispatcher to delete")) UPROPERTY(EditAnywhere, meta=(Description="Name of the event dispatcher to delete"))
FString Dispatcher; FString Dispatcher;
@@ -34,7 +34,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UBlueprint* BP = F.Walk(Blueprint).Cast<UBlueprint>(); UBlueprint* BP = F.Walk(BlueprintPath).Cast<UBlueprint>();
if (!BP) return; if (!BP) return;
FBPVariableDescription* Var = WingUtils::FindOneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Dispatcher"), WingOut::Stdout); FBPVariableDescription* Var = WingUtils::FindOneWithExternalID(Dispatcher, BP->NewVariables, TEXT("Dispatcher"), WingOut::Stdout);

View File

@@ -22,7 +22,7 @@ class UWing_GraphNode_Add : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target graph")) UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
FString Graph; FString GraphPath;
UPROPERTY(EditAnywhere, meta=(Description="Node type, from GraphNode_SearchTypes")) UPROPERTY(EditAnywhere, meta=(Description="Node type, from GraphNode_SearchTypes"))
FString Type; FString Type;
@@ -42,7 +42,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>(); UEdGraph* TargetGraph = F.Walk(GraphPath).Cast<UEdGraph>();
if (!TargetGraph) return; if (!TargetGraph) return;
FWingGraphActions GraphActions(TargetGraph); FWingGraphActions GraphActions(TargetGraph);

View File

@@ -20,7 +20,7 @@ class UWing_GraphNode_ChooseMenu : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target node")) UPROPERTY(EditAnywhere, meta=(Description="Target node"))
FString Node; FString NodePath;
UPROPERTY(EditAnywhere, meta=(Description="Menu item as shown by GraphNode_ShowMenu")) UPROPERTY(EditAnywhere, meta=(Description="Menu item as shown by GraphNode_ShowMenu"))
FString Item; FString Item;
@@ -36,7 +36,7 @@ private:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>(); UEdGraphNode* NodeObj = F.Walk(NodePath).Cast<UEdGraphNode>();
if (!NodeObj) return; if (!NodeObj) return;
FToolMenuContext Context; FToolMenuContext Context;

View File

@@ -19,7 +19,7 @@ class UWing_GraphNode_Dump : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target node")) UPROPERTY(EditAnywhere, meta=(Description="Target node"))
FString Node; FString NodePath;
UPROPERTY(EditAnywhere, meta=(Description="True to show minor node properties")) UPROPERTY(EditAnywhere, meta=(Description="True to show minor node properties"))
bool Details = false; bool Details = false;
@@ -33,7 +33,7 @@ private:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>(); UEdGraphNode* NodeObj = F.Walk(NodePath).Cast<UEdGraphNode>();
if (!NodeObj) return; if (!NodeObj) return;
WingGraphExport Exporter(NodeObj, false, Details); WingGraphExport Exporter(NodeObj, false, Details);

View File

@@ -20,7 +20,7 @@ class UWing_GraphNode_GetComment : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target node")) UPROPERTY(EditAnywhere, meta=(Description="Target node"))
FString Node; FString NodePath;
virtual void Register() override virtual void Register() override
{ {
@@ -30,7 +30,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>(); UEdGraphNode* FoundNode = F.Walk(NodePath).Cast<UEdGraphNode>();
if (!FoundNode) return; if (!FoundNode) return;
WingOut::Stdout.Printf(TEXT("Node: %s\n"), *WingUtils::FormatName(FoundNode)); WingOut::Stdout.Printf(TEXT("Node: %s\n"), *WingUtils::FormatName(FoundNode));

View File

@@ -24,7 +24,7 @@ class UWing_GraphNode_Remove : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Node to delete")) UPROPERTY(EditAnywhere, meta=(Description="Node to delete"))
FString Node; FString NodePath;
virtual void Register() override virtual void Register() override
{ {
@@ -35,7 +35,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>(); UEdGraphNode* FoundNode = F.Walk(NodePath).Cast<UEdGraphNode>();
if (!FoundNode) return; if (!FoundNode) return;
UEdGraph* Graph = FoundNode->GetGraph(); UEdGraph* Graph = FoundNode->GetGraph();

View File

@@ -20,7 +20,7 @@ class UWing_GraphNode_Rename : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target node")) UPROPERTY(EditAnywhere, meta=(Description="Target node"))
FString Node; FString NodePath;
UPROPERTY(EditAnywhere, meta=(Description="New name for the node")) UPROPERTY(EditAnywhere, meta=(Description="New name for the node"))
FString Name; FString Name;
@@ -34,7 +34,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>(); UEdGraphNode* FoundNode = F.Walk(NodePath).Cast<UEdGraphNode>();
if (!FoundNode) return; if (!FoundNode) return;
if (!WingUtils::CheckCanRename(FoundNode, Name, WingOut::Stdout)) return; if (!WingUtils::CheckCanRename(FoundNode, Name, WingOut::Stdout)) return;

View File

@@ -20,7 +20,7 @@ class UWing_GraphNode_SearchTypes : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target graph")) UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
FString Graph; FString GraphPath;
UPROPERTY(EditAnywhere, meta=(Description="Maximum number of results per query")) UPROPERTY(EditAnywhere, meta=(Description="Maximum number of results per query"))
int32 MaxResults = 50; int32 MaxResults = 50;
@@ -37,7 +37,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>(); UEdGraph* TargetGraph = F.Walk(GraphPath).Cast<UEdGraph>();
if (!TargetGraph) return; if (!TargetGraph) return;
FWingGraphActions GraphActions(TargetGraph); FWingGraphActions GraphActions(TargetGraph);

View File

@@ -20,7 +20,7 @@ class UWing_GraphNode_SetComment : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target node")) UPROPERTY(EditAnywhere, meta=(Description="Target node"))
FString Node; FString NodePath;
UPROPERTY(EditAnywhere, meta=(Description="Comment text to set")) UPROPERTY(EditAnywhere, meta=(Description="Comment text to set"))
FString Comment; FString Comment;
@@ -34,7 +34,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraphNode* FoundNode = F.Walk(Node).Cast<UEdGraphNode>(); UEdGraphNode* FoundNode = F.Walk(NodePath).Cast<UEdGraphNode>();
if (!FoundNode) return; if (!FoundNode) return;
FoundNode->NodeComment = Comment; FoundNode->NodeComment = Comment;

View File

@@ -17,11 +17,8 @@ class UWing_GraphNode_SetDefault : public UWingHandler
GENERATED_BODY() GENERATED_BODY()
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
FString Graph;
UPROPERTY(EditAnywhere, meta=(Description="Target node")) UPROPERTY(EditAnywhere, meta=(Description="Target node"))
FString Node; FString NodePath;
UPROPERTY(EditAnywhere, meta=(Description="Pin or property name")) UPROPERTY(EditAnywhere, meta=(Description="Pin or property name"))
FString Name; FString Name;
@@ -38,16 +35,11 @@ public:
// K2 graphs: set pin default values. // K2 graphs: set pin default values.
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
void HandleK2(UEdGraph* GraphObj, const UEdGraphSchema_K2* K2Schema) void HandleK2(UEdGraphNode* FoundNode, const UEdGraphSchema_K2* K2Schema)
{ {
WingFetcher F(GraphObj, WingOut::Stdout); UEdGraphPin* Pin = WingUtils::CheckGetPin(FoundNode, FName(*Name), WingOut::Stdout);
UWingGraphPinRef* PinRef = F.Node(Node).Pin(Name).Cast<UWingGraphPinRef>();
if (!PinRef) return;
UEdGraphPin* Pin = WingUtils::CheckGetPin(PinRef->Node, PinRef->PinName, WingOut::Stdout);
if (!Pin) return; if (!Pin) return;
UEdGraphNode* FoundNode = Pin->GetOwningNode();
if (Pin->Direction != EGPD_Input) if (Pin->Direction != EGPD_Input)
{ {
WingOut::Stdout.Printf(TEXT("error: %s is an output pin\n"), *WingUtils::FormatName(Pin)); WingOut::Stdout.Printf(TEXT("error: %s is an output pin\n"), *WingUtils::FormatName(Pin));
@@ -72,12 +64,8 @@ public:
// Material graphs: set material expression properties. // Material graphs: set material expression properties.
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
void HandleMaterial(UEdGraph* GraphObj) void HandleMaterial(UEdGraphNode* FoundNode)
{ {
WingFetcher F(GraphObj, WingOut::Stdout);
UEdGraphNode* FoundNode = F.Node(Node).Cast<UEdGraphNode>();
if (!FoundNode) return;
TArray<FWingProperty> All = FWingProperty::GetDetails(FoundNode, true); TArray<FWingProperty> All = FWingProperty::GetDetails(FoundNode, true);
FWingProperty *P = WingUtils::FindOneWithExternalID(Name, All, TEXT("Property"), WingOut::Stdout); FWingProperty *P = WingUtils::FindOneWithExternalID(Name, All, TEXT("Property"), WingOut::Stdout);
if (!P) return; if (!P) return;
@@ -92,12 +80,11 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
// Fetch the graph once. WingFetcher F(WingOut::Stdout);
WingFetcher GraphFetcher(WingOut::Stdout); UEdGraphNode* FoundNode = F.Walk(NodePath).Cast<UEdGraphNode>();
UEdGraph* GraphObj = GraphFetcher.Walk(Graph).Cast<UEdGraph>(); if (!FoundNode) return;
if (!GraphObj) return;
const UEdGraphSchema* Schema = GraphObj->GetSchema(); const UEdGraphSchema* Schema = FoundNode->GetGraph()->GetSchema();
const UEdGraphSchema_K2* K2Schema = Cast<UEdGraphSchema_K2>(Schema); const UEdGraphSchema_K2* K2Schema = Cast<UEdGraphSchema_K2>(Schema);
const UMaterialGraphSchema* MGSchema = Cast<UMaterialGraphSchema>(Schema); const UMaterialGraphSchema* MGSchema = Cast<UMaterialGraphSchema>(Schema);
@@ -107,8 +94,8 @@ public:
return; return;
} }
if (K2Schema) HandleK2(GraphObj, K2Schema); if (K2Schema) HandleK2(FoundNode, K2Schema);
else if (MGSchema) HandleMaterial(GraphObj); else if (MGSchema) HandleMaterial(FoundNode);
WingOut::Stdout.Printf(TEXT("Done.\n")); WingOut::Stdout.Printf(TEXT("Done.\n"));
} }

View File

@@ -15,11 +15,8 @@ class UWing_GraphNode_SetPosition : public UWingHandler
GENERATED_BODY() GENERATED_BODY()
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
FString Graph;
UPROPERTY(EditAnywhere, meta=(Description="Target node")) UPROPERTY(EditAnywhere, meta=(Description="Target node"))
FString Node; FString NodePath;
UPROPERTY(EditAnywhere, meta=(Description="New X position")) UPROPERTY(EditAnywhere, meta=(Description="New X position"))
int32 X = 0; int32 X = 0;
@@ -35,11 +32,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>(); UEdGraphNode* FoundNode = F.Walk(NodePath).Cast<UEdGraphNode>();
if (!TargetGraph) return;
WingFetcher FN(TargetGraph, WingOut::Stdout);
UEdGraphNode* FoundNode = FN.Node(Node).Cast<UEdGraphNode>();
if (!FoundNode) return; if (!FoundNode) return;
FoundNode->NodePosX = X; FoundNode->NodePosX = X;

View File

@@ -21,7 +21,7 @@ class UWing_GraphNode_ShowMenu : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target node")) UPROPERTY(EditAnywhere, meta=(Description="Target node"))
FString Node; FString NodePath;
virtual void Register() override virtual void Register() override
{ {
@@ -32,7 +32,7 @@ private:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraphNode* NodeObj = F.Walk(Node).Cast<UEdGraphNode>(); UEdGraphNode* NodeObj = F.Walk(NodePath).Cast<UEdGraphNode>();
if (!NodeObj) return; if (!NodeObj) return;
if (Cast<UMaterialGraphNode>(NodeObj)) if (Cast<UMaterialGraphNode>(NodeObj))

View File

@@ -18,7 +18,7 @@ class UWing_GraphPin_Connect : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target graph")) UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
FString Graph; FString GraphPath;
UPROPERTY(EditAnywhere, meta=(Description="Alternating source pin / target pin strings")) UPROPERTY(EditAnywhere, meta=(Description="Alternating source pin / target pin strings"))
FWingRestOfArgv SourcePin_TargetPin; FWingRestOfArgv SourcePin_TargetPin;
@@ -33,7 +33,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>(); UEdGraph* G = F.Walk(GraphPath).Cast<UEdGraph>();
if (!G) return; if (!G) return;
if ((SourcePin_TargetPin.Argv.Num() % 2) != 0) if ((SourcePin_TargetPin.Argv.Num() % 2) != 0)

View File

@@ -21,7 +21,7 @@ class UWing_GraphPin_Disconnect : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Target graph")) UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
FString Graph; FString GraphPath;
UPROPERTY(EditAnywhere, meta=(Description="Pin ID strings")) UPROPERTY(EditAnywhere, meta=(Description="Pin ID strings"))
FWingRestOfArgv Pins; FWingRestOfArgv Pins;
@@ -36,7 +36,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraph* G = F.Walk(Graph).Cast<UEdGraph>(); UEdGraph* G = F.Walk(GraphPath).Cast<UEdGraph>();
if (!G) return; if (!G) return;
int32 SuccessCount = 0; int32 SuccessCount = 0;

View File

@@ -20,7 +20,7 @@ class UWing_Graph_Dump : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to graph")) UPROPERTY(EditAnywhere, meta=(Description="Path to graph"))
FString Graph; FString GraphPath;
UPROPERTY(EditAnywhere, meta=(Description="True to show minor node properties")) UPROPERTY(EditAnywhere, meta=(Description="True to show minor node properties"))
bool Details = false; bool Details = false;
@@ -33,7 +33,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UEdGraph *G = F.Walk(Graph).Cast<UEdGraph>(); UEdGraph *G = F.Walk(GraphPath).Cast<UEdGraph>();
if (!G) return; if (!G) return;
WingGraphExport Exporter(G, true, Details); WingGraphExport Exporter(G, true, Details);

View File

@@ -1,59 +0,0 @@
#pragma once
#include "CoreMinimal.h"
#include "WingServer.h"
#include "WingBasics.h"
#include "Containers/BitArray.h"
#include "Containers/SparseArray.h"
#include "Test_TMaps.generated.h"
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
UCLASS()
class UWing_Test_TMaps : public UWingHandler
{
GENERATED_BODY()
public:
virtual void Register() override
{
UWingServer::AddHandler(this,
TEXT("Constructs a small TMap, TBitArray, and TSparseArray so that "
"a developer can set a breakpoint and inspect them with the "
"lldb data formatters."));
}
virtual void Handle() override
{
TMap<int32, FString> Map;
Map.Add(1, TEXT("one"));
Map.Add(2, TEXT("two"));
Map.Add(3, TEXT("three"));
Map.Add(42, TEXT("forty-two"));
TBitArray<> Bits;
Bits.Add(true);
Bits.Add(false);
Bits.Add(true);
Bits.Add(true);
Bits.Add(false);
// Add a few entries, then remove a middle one so the live set is
// non-contiguous. Exercises the sparse-array formatter against a hole.
TSparseArray<FString> Sparse;
Sparse.Add(TEXT("alpha"));
int32 BetaIdx = Sparse.Add(TEXT("beta"));
Sparse.Add(TEXT("gamma"));
Sparse.Add(TEXT("delta"));
Sparse.RemoveAt(BetaIdx);
TTuple<int32, FString, float, bool, FName> Tuple(1, TEXT("hello"), 3.14f, true, FName("world"));
// Set a breakpoint on the following line to inspect Map, Bits, and Sparse.
WingOut::Stdout.Printf(TEXT("Test_TMaps: Map has %d entries, Bits has %d bits, Sparse has %d entries.\n"),
Map.Num(), Bits.Num(), Sparse.Num());
}
};

View File

@@ -19,7 +19,7 @@ class UWing_Variables_Add : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to a blueprint, graph, or custom event node")) UPROPERTY(EditAnywhere, meta=(Description="Path to a blueprint, graph, or custom event node"))
FString Object; FString ObjectPath;
UPROPERTY(EditAnywhere, meta=(Description="Variable descriptions")) UPROPERTY(EditAnywhere, meta=(Description="Variable descriptions"))
FWingRestOfArgv Variables; FWingRestOfArgv Variables;
@@ -35,7 +35,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UObject* Obj = F.Walk(Object).Cast<UObject>(); UObject* Obj = F.Walk(ObjectPath).Cast<UObject>();
if (!Obj) return; if (!Obj) return;
WingVariables Vars; WingVariables Vars;

View File

@@ -19,7 +19,7 @@ class UWing_Variables_Dump : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to a blueprint, graph, or custom event node")) UPROPERTY(EditAnywhere, meta=(Description="Path to a blueprint, graph, or custom event node"))
FString Object; FString ObjectPath;
virtual void Register() override virtual void Register() override
{ {
@@ -30,7 +30,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UObject* Obj = F.Walk(Object).Cast<UObject>(); UObject* Obj = F.Walk(ObjectPath).Cast<UObject>();
if (!Obj) return; if (!Obj) return;
WingVariables Vars; WingVariables Vars;

View File

@@ -19,7 +19,7 @@ class UWing_Variables_Modify : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to a blueprint, graph, or custom event node")) UPROPERTY(EditAnywhere, meta=(Description="Path to a blueprint, graph, or custom event node"))
FString Object; FString ObjectPath;
UPROPERTY(EditAnywhere, meta=(Description="Variable descriptions")) UPROPERTY(EditAnywhere, meta=(Description="Variable descriptions"))
FWingRestOfArgv Variables; FWingRestOfArgv Variables;
@@ -35,7 +35,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UObject* Obj = F.Walk(Object).Cast<UObject>(); UObject* Obj = F.Walk(ObjectPath).Cast<UObject>();
if (!Obj) return; if (!Obj) return;
WingVariables Vars; WingVariables Vars;

View File

@@ -19,7 +19,7 @@ class UWing_Variables_Remove : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to a blueprint, graph, or custom event node")) UPROPERTY(EditAnywhere, meta=(Description="Path to a blueprint, graph, or custom event node"))
FString Object; FString ObjectPath;
UPROPERTY(EditAnywhere, meta=(Description="Variable descriptions")) UPROPERTY(EditAnywhere, meta=(Description="Variable descriptions"))
FWingRestOfArgv Variables; FWingRestOfArgv Variables;
@@ -34,7 +34,7 @@ public:
virtual void Handle() override virtual void Handle() override
{ {
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UObject* Obj = F.Walk(Object).Cast<UObject>(); UObject* Obj = F.Walk(ObjectPath).Cast<UObject>();
if (!Obj) return; if (!Obj) return;
WingVariables Vars; WingVariables Vars;

View File

@@ -25,7 +25,7 @@ class UWing_Widget_Add : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Widget blueprint to add the widget to")) UPROPERTY(EditAnywhere, meta=(Description="Widget blueprint to add the widget to"))
FString Blueprint; FString BlueprintPath;
UPROPERTY(EditAnywhere, meta=(Description="Widget type, from Widget_SearchTypes")) UPROPERTY(EditAnywhere, meta=(Description="Widget type, from Widget_SearchTypes"))
FString Type; FString Type;
@@ -49,7 +49,7 @@ public:
{ {
// Fetch the widget blueprint. // Fetch the widget blueprint.
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UWidgetBlueprint* BP = F.Walk(Blueprint).Cast<UWidgetBlueprint>(); UWidgetBlueprint* BP = F.Walk(BlueprintPath).Cast<UWidgetBlueprint>();
if (!BP) return; if (!BP) return;
// Resolve the widget type. // Resolve the widget type.

View File

@@ -23,7 +23,7 @@ class UWing_Widget_Remove : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to the widget, eg /Game/Widgets/WB_Test,widget:MyButton")) UPROPERTY(EditAnywhere, meta=(Description="Path to the widget, eg /Game/Widgets/WB_Test,widget:MyButton"))
FString Widget; FString WidgetPath;
virtual void Register() override virtual void Register() override
{ {
@@ -35,7 +35,7 @@ public:
{ {
// Walk to the widget. // Walk to the widget.
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UWidget* TargetWidget = F.Walk(Widget).Cast<UWidget>(); UWidget* TargetWidget = F.Walk(WidgetPath).Cast<UWidget>();
if (!TargetWidget) return; if (!TargetWidget) return;
// Get the widget blueprint and tree from the widget's outer chain. // Get the widget blueprint and tree from the widget's outer chain.

View File

@@ -23,7 +23,7 @@ class UWing_Widget_Reparent : public UWingHandler
public: public:
UPROPERTY(EditAnywhere, meta=(Description="Path to the widget, eg /Game/Widgets/WB_Test,widget:MyButton")) UPROPERTY(EditAnywhere, meta=(Description="Path to the widget, eg /Game/Widgets/WB_Test,widget:MyButton"))
FString Widget; FString WidgetPath;
UPROPERTY(EditAnywhere, meta=(Description="Name of the new parent widget. Must be a panel.")) UPROPERTY(EditAnywhere, meta=(Description="Name of the new parent widget. Must be a panel."))
FString Parent; FString Parent;
@@ -37,7 +37,7 @@ public:
{ {
// Walk to the widget. // Walk to the widget.
WingFetcher F(WingOut::Stdout); WingFetcher F(WingOut::Stdout);
UWidget* TargetWidget = F.Walk(Widget).Cast<UWidget>(); UWidget* TargetWidget = F.Walk(WidgetPath).Cast<UWidget>();
if (!TargetWidget) return; if (!TargetWidget) return;
// Get the widget blueprint from the widget's outer chain. // Get the widget blueprint from the widget's outer chain.