Skip to content
 
 

Repository files navigation

Klee: Redux

A standalone Unreal Engine Blueprint visualizer for the web, with some modifications to suit its use on my portfolio site: www.kris-j.com.

These modifications include: (This is still a work-in-progress. The following may change, shrink, or grow)

  • Editor-facing Node Names
  • Ability to open referenced Material Functions
  • Material graph inspection and Unreal-style preview-target selection (press W)
  • Node visuals that closer match the UE5 editor
  • Draggable nodes with a reset, and host-facing chrome colours
  • Copying a selection back out as Unreal-pasteable clipboard text

Material graphs

Klee accepts Unreal Material graph clipboard text, including the nested MaterialExpression object blocks produced by the editor. Material nodes use editor-facing captions when those values are serialized. This includes parameter names, custom descriptions, common expression names, and the exact asset name of a Material Function call. Unknown expression types receive a readable title derived from their Unreal class name.

The Material Function call stores both the asset name and canonical Unreal object path. The referenced function graph is not embedded in the parent clipboard data; a host can use the activation event below to resolve and load a separately supplied function graph.

Graph inspection and authored Material settings

display() automatically classifies clipboard text as blueprint, material, material-function, material-fragment, mixed, or unknown, and returns the same inspection object exposed by viewer.inspection:

const viewer = Klee.init(document.querySelector("canvas.klee"));
const inspection = viewer.display(source, {
    graph: {
        material: {
            domain: "MD_UI",
            blendMode: "BLEND_Translucent",
            shadingModel: "MSM_Unlit",
            useMaterialAttributes: false,
            unrealVersion: "5.7",
            // Optional exact editor-facing names; overrides built-in rules.
            rootInputs: ["Final Color", "Opacity"],
        },
    },
});

Klee prefers Material settings serialized in the pasted root/Material block, records whether each value was serialized, authored, or unknown, and warns when authored fallback metadata conflicts. Without an explicit rootInputs list, Klee only filters root pins for a deliberately small, versioned set of common UE5 UI-domain cases. Unsupported or incomplete metadata leaves the serialized pins unchanged; Klee does not claim complete Unreal-version parity.

Material preview targets

For a Material-family graph, select one Material node and press W, or use the keyboard-operable Preview toolbar button, to mark it as the preview target. Pressing W again returns to the Material root. With no selection, W clears an active node preview; multiple selections do not change the active target.

viewer.togglePreviewSelected();
viewer.clearPreview();
const state = viewer.getPreviewState();

canvas.addEventListener("klee:previewchange", event => {
    console.log(event.detail.nodeName, event.detail.reason);
});

The blue outline identifies the effective output target. This build does not compile Unreal expressions or render Material pixels: inspection and preview events explicitly report pixelRenderingAvailable: false, allowing a host to provide an honest unavailable state or attach a compatible renderer.

Copying nodes back to Unreal

Selecting nodes and pressing Ctrl+C, or Cmd+C on macOS, copies them as Unreal clipboard text, so they paste straight into a graph in the editor. Each node contributes its original object block; links to nodes that were not copied are dropped on paste, exactly as they are when copying a partial selection inside Unreal.

viewer.selectionText; // the same text, or "" when nothing is selected

With nothing selected the clipboard is left untouched rather than overwritten with an empty string.

Moving nodes

Dragging a node moves it and every other selected node, snapping to the 16px minor grid. The position the pasted graph gave each node is kept separately, so a layout can always be undone:

viewer.hasMovedNodes;        // true once anything has been dragged
viewer.resetNodePositions(); // returns true if it moved anything back

The toolbar shows a Reset layout button only while there is something to reset, and reloading a graph re-reads the authored positions.

Releasing a viewer

Klee.init starts an animation frame loop and installs listeners on window, document and the canvas. A host that mounts and unmounts the canvas repeatedly — a single-page application, most obviously — must release each viewer, or every mount leaves a frame loop and its listeners running:

const viewer = Klee.init(canvas);
// ...
viewer.destroy();

destroy() cancels the frame loop, detaches every listener, unloads the parsed scene, returns the canvas to the parent it had before the overlay wrapped it, and frees the instance registry slot. It is idempotent, Klee.get() stops returning a destroyed viewer, and the same canvas can be passed to Klee.init again afterwards.

Node activation

Double-clicking a rendered node dispatches a bubbling, cancelable klee:nodeactivate CustomEvent from the canvas. Its detail is a plain, serializable object:

const canvas = document.querySelector("canvas.klee");

canvas.addEventListener("klee:nodeactivate", (event) => {
    const {
        nodeName,
        nodeClass,
        title,
        expressionClass,
        assetName,
        objectPath,
        reference,
        references,
    } = event.detail;

    // reference is the first generic graph reference; references contains all.
    // Legacy assetName and objectPath remain for Material Function calls.
});

Every node activation includes nodeName, nodeClass, and title. expressionClass is included for Material expression nodes, while assetName and objectPath are included only when the node references a Material Function. The exported KLEE_NODE_ACTIVATE_EVENT constant contains the event name. Canvas nodes are not keyboard focus targets. Hosts that use node activation must provide an equivalent keyboard-operable control, such as a list of linked referenced graphs beside the canvas.

The generic reference/references contract covers Material Functions, Blueprint function calls, Blueprint macros, and collapsed graphs. References include the available asset path, graph/member name, GUID, self-context, and whether they are built in or navigable. Native /Script calls are marked as built-in and non-navigable; hosts should only open graph source that they have explicitly mapped.

Build minified JS

To build a minified JavaScript file of klee you have to install the development dependencies:

npm install

As soon as the dependencies are installed you can run the following command to build a minified JavaScript file.

npm run build

You can find the output at dist/klee.min.js relative to the root of the project directory.

Build the website

To build the complete static website for deployment, run:

npm ci
npm run build:site

The deployable website is written to site-dist/. This build copies the site from docs/ and replaces site-dist/js/klee.min.js with the freshly compiled library, so the deployed website cannot use a stale library bundle.

Deploy to Hostinger from Git

The Deploy Hostinger site GitHub Actions workflow runs after every push to main. It builds the complete website and publishes only the contents of site-dist/ to the deploy branch.

In Hostinger, connect the repository using Advanced → Git, select the deploy branch, set the root directory to public_html, and enable automatic deployment. Hostinger then receives a clean static site with index.html at the branch root; source files and development dependencies are not published.

Development setup

npm install
npm run dev

To preview the documentation site against the current source, run:

npm run docs

This compiles src/ straight to docs/js/klee.min.js, the path docs/index.html loads. That file is generated and git-ignored on purpose: a committed copy silently goes stale against src/, so the demo would show a library that no longer matches the code. npm run build:site writes the production bundle to the same path inside site-dist/.

About

A standalone Unreal Engine Blueprint visualizer for the web. Fork of klee.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages