CalmUI
Assets

Assets

Add images, Vector SVG icons, fonts, videos, and host surfaces to a CalmUI project.

Add an image, Vector SVG, or font

  1. Open Assets in the Activity Bar. Project Assets is the default subview.
  2. Click Import.
  3. Drag one or several files into the import area, or click Choose files.
  4. Review the generated asset IDs and edit them when needed.
  5. Click Import asset or Import N assets.
  6. Drag an imported asset into the code editor or a supported visual field.

Studio copies the file into the project, creates a stable asset://... address, and adds it to the asset list. Supported import files are PNG, JPG, WEBP, SVG, TTF, OTF, WOFF, and WOFF2; a video mapping is added to the manifest by hand, see Play a video asset, and so is a game-owned texture, see Show a host surface. SVG source is limited to 1 MiB and accepts only the static shape subset used by CalmUI; scripts, event handlers, external references, animation, filters, masks, gradients, text, and embedded images are rejected. After a successful import, the dialog closes and a short confirmation shows the new address. Assets appear as compact, collapsed rows. Drag the whole row to a supported target, click its thumbnail to open the preview, or expand the arrow to see the URI, source, references, and actions. Click the URI to copy it. Suggestions appear while you type an asset name.

The expanded actions can delete a project-local asset after confirmation. This removes its source file and manifest mapping and can be reverted with Undo. For an Unreal-only mapping, the same action removes only the mapping; it never deletes the referenced Unreal asset.

PNG and JPG images plus TTF and OTF fonts can be imported as Unreal host assets. SVG is registered as a vector asset instead: CalmUI validates its supported shapes and includes them in the package for Studio and Unreal. Use Insert as Icon to create <Icon src="asset://..." /> source from a Vector SVG mapping.

Play a video asset

A manifest entry with "type": "video" maps an asset://... address to an .mp4 or .webm file. H.264 MP4 is the reference format. The entry declares the intrinsic size, which is what layout uses, and may repeat with loop:

{
  "schemaVersion": 2,
  "assets": [
    {
      "uri": "asset://game-ui/menu-backdrop",
      "type": "video",
      "path": "media/menu-backdrop.mp4",
      "width": 1920,
      "height": 1080,
      "loop": true
    }
  ]
}

Entries without type: "video" stay images, so an existing manifest keeps its meaning. Use the address exactly like an image: background-image: url(asset://game-ui/menu-backdrop) with background-size: cover, or <img src="asset://game-ui/menu-backdrop" />. There is no video element and no video CSS property.

CalmUI never decodes the file: the host owns the surface. In Studio Preview one muted, inline <video> element per address feeds the WebGL2 canvas. Playback follows what the last rendered frame of the visible preview references:

  • a reference starts or resumes playback, and the first frame is decoded while paused so nothing flashes blank;
  • losing the reference pauses without rewinding, after a grace window of two frames and 250 ms, and the last frame stays on screen;
  • removing the mapping releases the element and its texture;
  • preview playback is always muted, and component script cannot play, pause or seek a video asset.

The Asset Browser marks these mappings Video, adds · loop when the entry loops, and shows the declared intrinsic size. A missing file, an unsupported extension, a file Studio cannot decode, or a missing width/height is reported on the mapping, the same way a broken image is.

A screenshot capture seeks every video to t=0 and waits for that frame before it renders, so goldens are deterministic. --time-ms advances the UI clock only; it does not seek video.

Show a host surface

A manifest entry with "type": "surface" maps an asset://... address to a texture the game owns and draws, typically a render target it updates every frame: a world map, a minimap, a character portrait. CalmUI shows it as an ordinary image and never reads its pixels. The entry declares the intrinsic size, which is what layout uses, and needs no source file:

{
  "schemaVersion": 2,
  "assets": [
    {
      "uri": "asset://game-ui/island-map",
      "type": "surface",
      "width": 1748,
      "height": 812
    }
  ]
}

width and height are required. hostAssetPath is optional: add the Content Browser path of a texture to have the game show it until it binds another, or leave it out and bind the texture at runtime by address, see Bind a render target as a surface. opaque is true by default: CalmUI draws the surface with its alpha forced to 1, because a render target the game draws into with materials ends up with alpha 0 and would otherwise show nothing. Set "opaque": false only for a render target that carries a meaningful alpha. The element's own CSS opacity and clip apply either way. path and loop do not apply to a surface and are ignored.

Use the address exactly like an image: background-image: url(asset://game-ui/island-map) with background-size: cover, or <img src="asset://game-ui/island-map" />. There is no surface element and no surface CSS property. Until the game binds a texture, nothing is drawn for the element; the rest of the screen is unaffected.

Studio has no game texture to show, so Preview paints a grey checkerboard where the surface goes. It has the declared proportions, so background-size, object-fit and cover or contain placement can be judged exactly as in the game. The Asset Browser marks these mappings Surface, shows the declared size, and reports a missing width/height. A surface with no hostAssetPath is listed as bound at runtime, not as a missing source.

Preserve image corners with nine-slice

Select an <img> in Preview or Hierarchy and use Nine-slice image in the Inspector. Studio writes normal component source rather than private metadata:

<img
  src="asset://game-ui/panel"
  data-calmui-slice="12 16 12 16"
  data-calmui-slice-scale="1"
  data-calmui-slice-mode="stretch"
/>

The four margins identify the corners to preserve, in top right bottom left order, using units from the original image. Scale sets how large those units appear in the UI. Choose Stretch to resize the center and edges, or Tile to repeat them. CalmUI reduces the corners proportionally if the image area is too small. Save and check the panel at both its smallest and largest intended sizes.

Find mistakes

The Problems panel reports:

  • an asset name used in a screen but missing from Assets;
  • a file that cannot be found;
  • an unsupported file type;
  • an asset entry that is no longer used.

Use the asset in Unreal

When Studio is connected to Unreal, saving the package imports or updates its images and fonts. SVG images are included in the package. A packaged game uses these prepared assets and does not need files elsewhere on your computer.

You can also map an asset://... name to an asset that already exists in the Unreal Content Browser.

On this page