Getting Started

← Back to index

This page takes you from an empty Unity project to a rendered HTML/CSS document on screen.

Requirements

Install

Add the package to Packages/manifest.json:

"com.weva": "https://github.com/<owner>/unityui.git?path=Packages/com.weva"

Or import locally: clone the repo, then Package Manager → Add package from disk → pick Packages/com.weva/package.json.

The Phase One Demo sample (Package Manager → Weva → Samples) is a complete scene that exercises the whole pipeline end-to-end; import it to confirm the package works before authoring your own UI.

Author the HTML/CSS

Drop .html and .css files into Assets/UI/ — Unity imports them as TextAssets. A document references its stylesheet with a <link>:

<!-- Assets/UI/menu.html -->
<link rel="stylesheet" href="menu.css" />
<main class="menu">
  <h1>My Game</h1>
  <button id="start" on-click="OnStart">Start</button>
</main>
/* Assets/UI/menu.css */
.menu { display: flex; flex-direction: column; gap: 16px; padding: 24px; }
button { padding: 8px 16px; border-radius: 8px; background: #4f46e5; color: white; }
button:hover { background: #6366f1; }

You can also assign stylesheets directly in the inspector (see below) instead of, or in addition to, <link>.

Mount the document

WevaDocument (component menu Weva → UI Document) is the author-facing MonoBehaviour. It holds your HTML + stylesheet TextAssets and runs the pipeline in OnEnable.

Inspector fields map to these properties:

PropertyMeaning
DocumentAssetThe .html TextAsset.
StylesheetAssetsZero or more .css TextAssets, applied in order.
RendererBackendAuto (URP if present, else IMGUI), IMGUI, or URP.
SortingOrderPaint order across multiple documents (Order).
ViewportOverrideFixed layout viewport in px; (0,0) = track the screen.
PrefersDarkColorSchemeSeeds @media (prefers-color-scheme) / light-dark().
EnableHotReloadWatch the source files and rebuild on edit (editor-on by default).
AutoRebuildOnChangeRebuild when inspector fields or the viewport change.

OnEnable auto-attaches a Forms.Bridge.UnityInputController so pointer and keyboard input work without manual wiring.

Wire a controller

Attach a controller script next to the WevaDocument and register it:

using UnityEngine;
using Weva;
using Weva.Binding;

public sealed class MainMenu : MonoBehaviour {
    [UIBind] public int CoinCount;

    void Awake() => GetComponent<WevaDocument>().SetController(this);

    public void OnStart() => SceneManager.LoadScene("Game");
}

See AuthoringGuide.md for the full binding, event, and form story.

URP render setup

The production renderer is a ScriptableRendererFeature. Add UIBatchedRendererFeature (or UIRendererFeature) to your URP Renderer asset's Renderer Features list. It injects a render pass after RenderPassEvent.AfterRenderingPostProcessing and draws the UI directly into the camera color target (zero intermediate blit). Set RendererBackend = URP on the document to force this path.

Without the feature, set RendererBackend = Auto or IMGUI to fall back to IMGUIDocumentRenderer — fine for editor testing, not for shipping.

See Rendering for the full render pass description.

Viewport sizing

Weva uses a logical pixel model: 1px = 1 logical pixel, rem/em derive from a 16px base font size (matching CSS). The layout viewport — what vw/vh and @media (width) resolve against — is the UI surface, not the OS window, which matters for split-screen and embedded UI.

WevaDocument resolves the current viewport in this priority order:

  1. ViewportOverride if both components are > 0.
  2. ReferenceCamera.pixelWidth/Height if a camera is assigned.
  3. The current render-target size (pushed by the URP pass via PrepareForRenderViewport).
  4. Screen.width/height, then Camera.main, then the package default.

When the Game View resizes in Play mode, Update detects the delta and reruns layout against the new viewport — a lighter pass than a full Rebuild(). On mobile, Screen.safeArea is piped into env(safe-area-inset-*) automatically.

Hot reload

With EnableHotReload on (editor default), editing a watched .html or .css file in Play mode reparses and rebuilds without a domain reload; controller state and [UIBind] values survive. For programmatically-built UI with no source file, call doc.Rebuild().


Next: Supported HTML · Supported CSS