Quartz UI ↗
Browse docs
On this page
Private preview · 0.57.0-devView Markdown

Sounds, GAS, motion, and textures

0.57.0-dev · beta source documentation. Native, Blueprint, Editor and rendering examples are source-reviewed, not executed in Unreal during this scan. See validation and limits.

These integrations keep Unreal resources and gameplay ownership native. The browser receives semantic names, immutable values, or issued image URLs. Start with the exact-player shell from setup.

Semantic sound

Create a UQuartzUISoundSet Data Asset. Add an FQuartzUISoundEntry for ui.confirm with a soft sound reference; optionally preload small latency-critical cues. Set it as the project's Default Sound Set. The page uses the shipped transport:

const result = await client.request('quartzui.sound.play', { sound: 'ui.confirm' });
// Inspect result.routed and optional reason; the UI action itself must not await audio.

UQuartzUISoundSubsystem belongs to one LocalPlayer. PushSoundSet adds an override; RemoveSoundSet removes the newest matching push. Resolution searches newest pushed sets then the default. Balance operations in the same feature lifetime. Each set permits 128 entries; admitted cues are bounded to 32 per second per player. Volume/pitch are clamped. Invalid tags, absent mappings, declined handlers, and rate limits have explicit outcomes.

For another audio backend, subclass UQuartzUISoundHandler: Initialize once, Handle Sound for each cue, Shutdown at subsystem teardown. Handler precedence is resolving set, project default, then built-in async-load/PlaySound2D. A listener on On Sound Requested is an alternative without a sound set; listeners also fire alongside mapped playback, so avoid double playback when using both. No browser-supplied asset paths are accepted. The npm-style playSound2D wrapper in the old guide is not shipped in this repository.

Gameplay Ability System

Enable GameplayAbilities and restart the host. Add QuartzUI GAS Binding (UQuartzUIGASBindingComponent) to the local PlayerController, HUD, pawn, or valid owner chain. Leave Config unset for automatic discovery and Browser Ability Action Policy Disabled for observation. QuartzUIGAS loads only when its optional dependency is enabled; native consumers include its headers via a client module dependency.

const stopAttributes = client.subscribeState('quartzui.gas.attributes', snapshot => {
  renderAttributes(snapshot); // Decode the generated FQuartzUIGASAttributeState shape.
});

The adapter snapshots context, attributes, tags, abilities, and status effects; matching events follow state updates. UQuartzUIGASConfig provides aliases, mappings, costs, failure labels, and action permissions. With automatic discovery disabled, mappings become the complete exposed allowlist. UQuartzUIGASResolver is the project seam for unusual ASC ownership; the exact-player guard still applies.

To permit a browser action, explicitly choose ExplicitMappings or AllDiscovered, then use the generated quartzui.gas.activate / quartzui.gas.cancel request shape. Do not infer request field names or treat UI affordability as authoritative. Unreal validates IDs, ownership, grants, rates, costs, cooldowns, and permission. No ASC/spec handles or UObject references cross the bridge.

The component owns retries, source replacement, and delegate cleanup. For custom feature ownership, UQuartzUIGASBlueprintLibrary creates a scope; attach that scope to the exact shell and detach on deactivation. Internal activate/cancel endpoint classes and observed-record structs are owned by that scope; do not instantiate an alternative endpoint for the reserved names.

Camera-driven UI motion

Add QuartzUI Motion (UQuartzUIMotionComponent) to the local PlayerController. It samples in PostUpdateWork and publishes quartzui.motion to an existing presented shell at a bounded 1–60 Hz. The component does not create the shell. The snapshot includes enabled, headingDegrees, tilt, roll, offsets, shake, intensity, and revision.

Minimal use: call Add Motion Impulse with screen direction (1,0) and strength 0.25, then consume the snapshot in your web CSS transform. Call Set Motion Effects Enabled(false) for a reduced-motion preference and also suppress web-side animation. Do not assume the component automatically consumes every presentation preference. EndPlay clears/publishes disabled state; the component owns its tick samples. Compass heading and visual shake are presentation data, not simulation input.

Static Unreal textures in HTML

For a loaded, cook-reachable UTexture2D, use the logical view's UQuartzUITextureResources:

const FString Url = View->GetTextureResources()->RegisterTexture(Texture);
// Empty: pending, unsupported, or failed. Republish when GetRevision changes.

Include QuartzUIView.h and QuartzUITextureResources.h; retain/load the texture through ordinary Unreal ownership before registration. Publish only a ready nonempty URL in your DTO. On the page, validate with unrealTextureResource(value, document.baseURI) from texture-resources.mjs, then assign the result to an image src if non-null.

This is one queued texture per tick, one-time GPU readback and PNG encoding, cached per UObject. It may spike the first frame. Bounds include 256 textures/view, longest output side 1024, 8 MiB encoded/image, and 128 MiB encoded/process. Streaming or pixel changes do not refresh an existing snapshot. ReleaseAll revokes URLs and permits re-registration; closing the view revokes all its URLs and releases references. Same-origin code given another view's URL can read it: the URL is a capability, not per-document authentication.

This API does not import live render targets, materials, virtual textures, or HDR-preserving frames into Chromium. It is not zero-copy.

Bake authored textures instead

For a large immutable icon catalog, use Scripts/texture_resources.py from Unreal Editor Python. Supply explicit stable IDs, full Texture2D object paths, a project-owned output directory, and unreal_exporter():

from pathlib import Path
from texture_resources import bake, unreal_exporter
bake([{"id": "track-preview", "asset": "/Game/UI/T_Track.T_Track"}],
     Path(project_generated_directory) / "textures", unreal_exporter())

Put the plugin Scripts directory on Python's module path and define project_generated_directory in your host tooling. The editor must have Python support and exportable texture source. The tool validates the whole batch before replacing owned output, hashes/deduplicates PNGs, and preserves existing output on failure. It refuses unsafe paths and unowned output roots.

Bundle the manifest as compiled JS data, or otherwise stage it through a validated host rule: UAT may omit raw .json files. Use textureResource(manifest, 'track-preview', baseUrl) to resolve a same-origin file; missing IDs return null. The bake itself does not make the source asset cook-reachable or prove in-game alpha/color.

Sound guide (source: Documentation/UISounds.md), GAS guide (source: Documentation/GAS.md), motion source (source: Source/QuartzUIRuntime/Public/QuartzUIMotionComponent.h), texture guide (source: Documentation/TextureResources.md). Native/editor examples remain unexecuted in this scan.