Some usability tweaks for UE Wingman.

This commit is contained in:
2026-04-14 02:28:22 -04:00
parent 49331773bf
commit 7296847fb5
4 changed files with 56 additions and 51 deletions

View File

@@ -44,7 +44,9 @@ public:
virtual void Register() override virtual void Register() override
{ {
UWingServer::AddHandler(this, UWingServer::AddHandler(this,
TEXT("Connect pins between nodes in a graph (Blueprint or Material).")); TEXT("Connect pins between nodes in a graph (Blueprint or Material). "
"Pin IDs use fetcher path syntax relative to the graph, eg: "
"node:K2Node_CallFunction_0,pin:ReturnValue"));
} }
virtual void Handle() override virtual void Handle() override
{ {

View File

@@ -15,19 +15,6 @@
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
USTRUCT()
struct FDisconnectPinEntry
{
GENERATED_BODY()
UPROPERTY()
FString Pin;
UPROPERTY(EditAnywhere, meta=(Optional))
FString TargetPin;
};
UCLASS() UCLASS()
class UWing_GraphPin_Disconnect : public UWingHandler class UWing_GraphPin_Disconnect : public UWingHandler
{ {
@@ -37,14 +24,15 @@ public:
UPROPERTY(EditAnywhere, meta=(Description="Target graph")) UPROPERTY(EditAnywhere, meta=(Description="Target graph"))
FString Graph; FString Graph;
UPROPERTY(EditAnywhere, meta=(Description="Array of {pin, targetPin?} objects. If targetPin is omitted, all connections on the pin are broken.")) UPROPERTY(EditAnywhere, meta=(Description="Array of pin ID strings"))
FWingJsonArray Disconnections; FWingJsonArray Pins;
virtual void Register() override virtual void Register() override
{ {
UWingServer::AddHandler(this, UWingServer::AddHandler(this,
TEXT("Disconnect pins in a graph (Blueprint or Material). " TEXT("Disconnect all connections on the specified pins. "
"Can disconnect a specific link or all links on a pin.")); "Pin IDs use fetcher path syntax relative to the graph, eg: "
"node:K2Node_CallFunction_0,pin:ReturnValue"));
} }
virtual void Handle() override virtual void Handle() override
{ {
@@ -55,46 +43,25 @@ public:
int32 SuccessCount = 0; int32 SuccessCount = 0;
int32 TotalDisconnected = 0; int32 TotalDisconnected = 0;
FDisconnectPinEntry Entry; for (const TSharedPtr<FJsonValue>& PinVal : Pins.Array)
TArray<FWingProperty> EntryProps = FWingProperty::GetAll(&Entry);
for (const TSharedPtr<FJsonValue>& DiscVal : Disconnections.Array)
{ {
if (!FWingProperty::PopulateFromJson(EntryProps, *DiscVal, false, WingOut::Stdout)) continue; FString PinPath;
if (!PinVal->TryGetString(PinPath))
{
WingOut::Stdout.Print(TEXT("ERROR: Expected a string pin ID.\n"));
continue;
}
WingFetcher FP(G, WingOut::Stdout); WingFetcher FP(G, WingOut::Stdout);
UWingGraphPinRef* PinRef = FP.Walk(Entry.Pin).Cast<UWingGraphPinRef>(); UWingGraphPinRef* PinRef = FP.Walk(PinPath).Cast<UWingGraphPinRef>();
if (!PinRef) continue; if (!PinRef) continue;
UEdGraphPin* Pin = WingUtils::CheckGetPin(PinRef->Node, PinRef->PinName, WingOut::Stdout); UEdGraphPin* Pin = WingUtils::CheckGetPin(PinRef->Node, PinRef->PinName, WingOut::Stdout);
if (!Pin) continue; if (!Pin) continue;
int32 DisconnectedCount = 0; int32 DisconnectedCount = Pin->LinkedTo.Num();
if (DisconnectedCount > 0)
if (!Entry.TargetPin.IsEmpty())
{ {
WingFetcher FT(G, WingOut::Stdout); Pin->BreakAllPinLinks(true);
UWingGraphPinRef* TargetRef = FT.Walk(Entry.TargetPin).Cast<UWingGraphPinRef>();
if (!TargetRef) continue;
UEdGraphPin* Target = WingUtils::CheckGetPin(TargetRef->Node, TargetRef->PinName, WingOut::Stdout);
if (!Target) continue;
if (!Pin->LinkedTo.Contains(Target))
{
WingOut::Stdout.Printf(TEXT("Error: %s.%s is not connected to %s.%s\n"),
*WingUtils::FormatName(Pin->GetOwningNode()), *WingUtils::FormatName(Pin),
*WingUtils::FormatName(Target->GetOwningNode()), *WingUtils::FormatName(Target));
continue;
}
Pin->BreakLinkTo(Target);
DisconnectedCount = 1;
}
else
{
DisconnectedCount = Pin->LinkedTo.Num();
if (DisconnectedCount > 0)
{
Pin->BreakAllPinLinks(true);
}
} }
WingOut::Stdout.Printf(TEXT("Disconnected %d link(s) from %s.%s\n"), WingOut::Stdout.Printf(TEXT("Disconnected %d link(s) from %s.%s\n"),
@@ -105,6 +72,6 @@ public:
} }
WingOut::Stdout.Printf(TEXT("Done: %d/%d succeeded, %d links broken.\n"), WingOut::Stdout.Printf(TEXT("Done: %d/%d succeeded, %d links broken.\n"),
SuccessCount, Disconnections.Array.Num(), TotalDisconnected); SuccessCount, Pins.Array.Num(), TotalDisconnected);
} }
}; };

View File

@@ -169,6 +169,36 @@ void UWingManualSections::MaterialEditing()
)); ));
} }
void UWingManualSections::NodeContextMenus()
{
WingOut::Stdout.Print(TEXT(
"\n NODE CONTEXT MENUS:"
"\n"
"\n GraphNode_ShowMenu and GraphNode_ChooseMenu give access"
"\n to the node context menu. This menu includes both node"
"\n operations and pin operations (e.g. Split Struct Pin,"
"\n Add Pin)."
"\n"
));
}
void UWingManualSections::VariableGettersAndSetters()
{
WingOut::Stdout.Print(TEXT(
"\n VARIABLE GETTERS AND SETTERS:"
"\n"
"\n Access to local vars, function parameters, and "
"\n blueprint vars is through getter and setter nodes. "
"\n These can be found in GraphNode_SearchTypes by "
"\n searching for 'Variable'. Some examples:"
"\n"
"\n SKEL_WB_Menu_C|Variables|Default|GetPlaceTangible"
"\n SKEL_WB_Menu_C|Variables|Default|SetPlaceTangible"
"\n SKEL_WB_Menu_C|Variables|WB_Menu|GetMenuPanel"
"\n"
));
}
void UWingManualSections::ImportantCommands() void UWingManualSections::ImportantCommands()
{ {
WingOut::Stdout.Print(TEXT( WingOut::Stdout.Print(TEXT(

View File

@@ -42,4 +42,10 @@ public:
UFUNCTION() UFUNCTION()
static void ImportantCommands(); static void ImportantCommands();
UFUNCTION()
static void NodeContextMenus();
UFUNCTION()
static void VariableGettersAndSetters();
}; };