Skip to content
Development
Skill

/hz-unity-meta-quest-ui

Configures Unity UI for Meta VR and Horizon OS VR development — world-space canvases, TextMesh Pro setup, comfortable sizing, viewing distances, and interaction readiness.

From plugin
meta-vr
24936 skills1 MCP

Claude Code

$ npx -y skills add meta-quest/agentic-tools --skill hz-unity-meta-quest-ui --agent claude-code

SKILL.md

hz-unity-meta-quest-ui.SKILL.md
name: hz-unity-meta-quest-ui
license: Apache-2.0
description: Configures Unity UI for Meta VR and Horizon OS VR development — world-space canvases, TextMesh Pro setup, comfortable sizing, viewing distances, and interaction readiness.

Meta VR UI Setup

When to use this skill

Use this skill automatically when:

  • Setting up a Canvas for VR
  • Creating UI text with TextMesh Pro in a VR project
  • Adding buttons, sliders, or other interactive UI in VR
  • User reports pink/magenta text, unclickable buttons, or UI sizing issues in VR
  • Configuring VR interaction (ray or poke) on a Canvas

Driving the Editor

Build the UI against an open Editor with `unity-cli` rather than hand-editing scene YAML — the Editor applies changes to the actual active scene.

unity status --format json          # look for state "ready"
unity command run_script --file AgentScripts/BuildUI.cs --entry BuildUI.Run --format json

Canvas construction is multi-component work, so it belongs in a `run_script` `.cs` file (kept **outside `Assets/`**, path relative to the project root) rather than a chain of single commands. Add `--dry_run true` to compile-check a script before it mutates the scene — but read the verdict from **`data.result.success`**: a compile failure still returns outer `success: true` and exit code `0`, with the errors in `data.result.diagnostics`. Connecting, `--project-path`, and Safe Mode recovery are in the **`unity-cli`** skill; MCP equivalents are in [references/unity-mcp-fallback.md](references/unity-mcp-fallback.md).

Single-property reads and writes are cheaper as direct commands than as a script:

unity command get_component_properties --target MenuUI --type Canvas --format json
unity command set_transform --target MenuUI --position "[0,1.5,2]" --format json
unity command find_gameobjects --name MenuUI --format json

Array parameters take a **JSON array in one argument** (`--position "[0,1.5,2]"`). Space- or comma-separated components are rejected with `INVALID_COMMAND_ARGS`. Note `set_transform` writes **local** position — see the **unity-placement** skill for parented canvases.

Prerequisite: TMP Essential Resources

Before creating ANY VR UI, verify TMP resources are imported:

unity command find_assets --name "LiberationSans SDF" --format json

A `data.result.count` of `0` means they are missing — use the **tmp-resources** skill before proceeding.

Step 1: Create World Space Canvas

// AgentScripts/BuildUI.cs
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.UI;

public static class BuildUI
{
    public static string Run()
    {
        // Adapt the name to match your canvas (e.g., "MainMenu", "SettingsUI")
        var go = new GameObject("MenuUI");
        var canvas = go.AddComponent<Canvas>();
        canvas.renderMode = RenderMode.WorldSpace;

        go.AddComponent<GraphicRaycaster>();

        // Remove CanvasScaler — not appropriate for VR
        var scaler = go.GetComponent<CanvasScaler>();
        if (scaler != null)
            Object.DestroyImmediate(scaler);

        var rt = go.GetComponent<RectTransform>();
        rt.localScale = new Vector3(0.001f, 0.001f, 0.001f);
        rt.sizeDelta = new Vector2(1920f, 1080f);
        rt.position = new Vector3(0f, 1.5f, 2f);

        Undo.RegisterCreatedObjectUndo(go, "Create VR Canvas");
        EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
        return $"Created VR Canvas '{go.name}'. Scale: {rt.localScale}, Size: {rt.sizeDelta}, Position: {rt.position}";
    }
}

Persist it when the shape is right:

unity command save_scene --format json

Canvas rules

  • **Render Mode**: Always World Space. Screen Space modes break stereo rendering.
  • **Scale**: 0.001 on all axes (1 unit in canvas = 1mm in world).
  • **CanvasScaler**: Remove it. Physical size is controlled by world scale, not screen adaptation.
  • **Distance**: Place 1.5-3m from user. Never closer than 0.5m. Max 5m for readable text.
  • **Physical size formula**: `Canvas sizeDelta * scale = meters`. Example: 1920 * 0.001 = 1.92m wide.

Step 2: Create child UI elements

All child elements (panels, buttons, text) must follow these rules:

  • **localScale**: Always `[1, 1, 1]`. Never scale children to compensate for canvas scale.
  • **localPosition.z**: Always `0`. Children must sit on the canvas plane.
  • **Size control**: Use `RectTransform.sizeDelta` and anchors, never scale.
// AgentScripts/BuildPanel.cs
using TMPro;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.UI;

public static class BuildPanel
{
    public static string Run()
    {
        // Replace "MenuUI" with the actual canvas name used in Step 1
        var canvas = GameObject.Find("MenuUI");
        if (canvas == null) return "ERROR: Canvas 'MenuUI' not found.";

        // Panel
        var panel = new GameObject("ButtonPanel");
        panel.transform.SetParent(canvas.transform, false);
        var panelRT = panel.AddComponent<RectTransform>();
        panelRT.localScale = Vector3.one;
        panelRT.sizeDelta = new Vector2(800f, 600f);
        var panelImg = panel.AddComponent<Image>();
        panelImg.color = new Color(0.1f, 0.1f, 0.1f, 0.95f);
        panelImg.raycastTarget = false;

        var layout = panel.AddComponent<VerticalLayoutGroup>();
        layout.spacing = 50f;
        layout.padding = new RectOffset(80, 80, 100, 100);
        layout.childAlignment = TextAnchor.MiddleCenter;

        // Button
        var btnGO = new GameObject("StartButton");
        btnGO.transform.SetParent(panel.transform, false);
        var btnRT = btnGO.AddComponent<RectTransform>();
        btnRT.localScale = Vector3.one;
        btnRT.sizeDelta = new Vector2(400f, 120f);
        var btnImg = btnGO.AddComponent<Image>();
        btnImg.color = new Color(0.2f, 0.6f, 1f, 1f);
        btnGO.AddComponent<Button>();

        // B
Read more
@meta-quest
Ships withmeta-vr

Agentic skills and tools for Meta VR and Horizon OS development.

24936 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
249
Star history of meta-quest/agentic-tools on GitHub, a chart by star-history.com

Other skills on meta-vr.

hz-android-2d-porting

hz-android-2d-porting

Guides porting existing Android 2D apps to Meta VR and Horizon OS — input adaptation, panel layout, and design requirements. Use…

@meta-quest@meta-questInstall Skill
hz-api-upgrade

hz-api-upgrade

Upgrades Meta VR apps to newer Horizon OS SDK versions — migration guides, deprecated API replacements, changelog. Use when…

@meta-quest@meta-questInstall Skill
hz-immersive-designer

hz-immersive-designer

Guides design of comfortable, intuitive VR/MR experiences for Meta VR and Horizon OS — comfort guidelines, interaction patterns,…

@meta-quest@meta-questInstall Skill
hz-iwsdk-webxr

hz-iwsdk-webxr

Builds WebXR experiences for Meta VR and Horizon OS using the Immersive Web SDK (IWSDK) — ECS architecture, Three.js integration,…

@meta-quest@meta-questInstall Skill
hz-metavrx-layout-sdk

hz-metavrx-layout-sdk

Build multi-window Meta Horizon OS experiences with the MetaVrx Layout SDK in Jetpack Compose or React Native. Covers framework…

@meta-quest@meta-questInstall Skill
hz-metavrx-ui-set

hz-metavrx-ui-set

Builds app UI for Meta VR and Horizon OS with the MetaVrx UI Set, a Jetpack Compose component library and design system. Covers…

@meta-quest@meta-questInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about hz-unity-meta-quest-ui.

Which coding agents can use hz-unity-meta-quest-ui?
hz-unity-meta-quest-ui installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.