Vai ai contenuti
File multimediali per l'articolo UMG Binding Surgeon - Rewrite UMG Bindings That Poll Every Frame (UE 5.8): 1

Descrizione

UMG's "Create Binding" button is the most expensive convenience in Unreal

Every property binding it creates is polled by Slate every single frame, and each one that points at a Blueprint function pays a VM call to do it. Epic documents this as an anti-pattern and ships no tool that enforces it.

This plugin finds every one of them, rewrites the ones it can prove are safe, and refuses the rest by name.

What it does
  • Scans without loading. Widget Blueprints are triaged on asset-registry tags first, so blueprints carrying no bindings are never opened at all.

  • Rewrites what it can prove. A bound function whose graph is a single pure variable read becomes a native property binding - same value, no Blueprint call.

  • Refuses everything else, with the specific reason. Eleven distinct named refusals, each printed beside the binding it belongs to.

  • Gates CI. -Budget=N fails the build when more than N bindings still poll through a Blueprint call.

The refusals are the point

"Not eligible" is not a reason anyone can act on. This tool prints what it actually found in your project:

  • the bound function reads 2 variables, so no single change can drive the update

  • the bound function graph contains K2Node_CallFunction, which this tool cannot prove is free of side effects

  • widget 'NameText' is driven by animation 'NameplateFadeIn', which may fight a pushed value

  • widget 'LevelText' has no bindable 'RenderOpacityDelegate', so this is an event binding rather than a per-frame attribute binding

  • the bound path walks 2 objects, and this tool cannot prove the intermediate ones notify on change

Every ambiguity resolves toward NOT rewriting. There is no branch that promotes a binding because nothing was found to object to - the rewrite tier is granted only by a positive structural proof. The thing it would otherwise be rewriting is your shipping UI.

Before committing any patch the tool hands the rewritten path to FEditorPropertyPath::Validate, the same check UMG's own compiler runs, and carries the engine's error text through verbatim if it is refused. The last word on whether a rewrite is legal belongs to Unreal, not to this plugin.

Safety
  • Dry run by default. -Apply is required before anything is written.

  • Every change is recorded in a manifest, and -Revert=<manifest> puts it all back.

  • It re-scans after applying. The fix pass's own success count is a claim; the re-scan is the evidence.

  • Structural, not profiled. The report shows the structural cost class of each read and says plainly that nothing is profiled. This plugin will not quote you a millisecond figure it never measured.

Getting Started

The plugin adds no toolbar button and no menu entry by design - it is a commandlet, so it runs unattended in CI as well as on a workstation. To launch it:

  1. Install: copy the UMGBindingSurgeon folder into your project's Plugins/ directory (create it if it does not exist), so you have <YourProject>/Plugins/UMGBindingSurgeon/UMGBindingSurgeon.uplugin.

  2. Enable: open the project, then Edit → Plugins → Editor, find UMG Binding Surgeon, tick Enabled, and restart the editor when prompted.

  3. Run a scan (writes nothing) from a command prompt in your project folder:
    "C:\Program Files\Epic Games\UE_5.8\Engine\Binaries\Win64\UnrealEditor-Cmd.exe" "<YourProject>.uproject" -run=UMGBindingSurgeon -Paths=/Game -Report=BindingMap.html

  4. Open BindingMap.html in any browser. That is the Binding Cost Map shown in the screenshots on this page: one card per Widget Blueprint, one generated mark per binding, every refusal printed beside the binding it belongs to.

  5. Apply the rewrites once you are happy with the dry run, recording a manifest so it can be undone:
    ... -run=UMGBindingSurgeon -Paths=/Game -Apply -Manifest=ubs_manifest.json

  6. Undo everything if you change your mind:
    ... -run=UMGBindingSurgeon -Revert=ubs_manifest.json -Apply

  7. Gate your build in CI by adding -Budget=N; the commandlet exits non-zero when more than N bindings still poll through a Blueprint call.

Full documentation: https://github.com/onefreeman1337/csaf-releases/blob/main/docs/umg-binding-surgeon/README.md

Technical Information

Features:

  • Project-wide scan of UMG property bindings, triaged on asset-registry tags so blueprints without bindings are never loaded

  • Three-tier classification: already a native read, provably rewritable, or refused with a named reason

  • Eleven distinct refusal reasons, each printed with the specific detail found in your project

  • Automatic rewrite of provable single-variable getters onto the engine's native property path

  • Engine-validated patches - FEditorPropertyPath::Validate gets the last word before any commit

  • Manifest of every change, with a full -Revert

  • Self-contained HTML Binding Cost Map with one procedurally generated mark per binding

  • CI budget gate via -Budget=N

  • Dry run by default; -Apply required to write

Code Modules: UMGBindingSurgeon (Editor)

Number of Blueprints: 0

Number of C++ Classes: 13 public types (7 classes, 6 structs) plus 2 enums

Network Replicated: No (editor-only tooling; nothing ships into a packaged build)

Supported Development Platforms: Windows

Supported Target Build Platforms: Windows

Example Project: No. The plugin runs against your own project's Widget Blueprints; a sample project would only demonstrate bindings you already have.

Documentation: https://github.com/onefreeman1337/csaf-releases/blob/main/docs/umg-binding-surgeon/README.md

Important/Additional Notes: Built and verified against Unreal Engine 5.8 only - that is the only engine installed on our build machine and the only one the packaging gate has run against, and we do not claim versions we have not built. Windows (Win64) only, matching the descriptor's PlatformAllowList. Editor-only: the module type is Editor and nothing is included in a packaged game. Ships as raw, readable C++ with no obfuscation.

Formati inclusi