scenario-unity-ui について
uGUI または UI Toolkit で画面を構築する UI 開発者向けの Unity スキルです。レスポンシブレイアウト、入力とフォーカス、ローカライズ、描画コストを扱い、キャプチャ、監査、テストで検証します。
主な機能
- 01uGUI と UI Toolkit の選択
- 02画面サイズに応じたレイアウト
- 03マウス・タッチ・キーボード・ゲームパッド対応
- 04ローカライズとフォントグリフの確認
- 05UI キャプチャ・監査・性能カウンター
活用シーン
- 01スマートフォンや 4K 向けメニューの構築
- 02UI システム間のナビゲーションとフォーカス検証
- 03翻訳テキストと不足グリフの確認
- 04UI 再構築と描画コストの特定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-unity-uiインストール後、Claude Code で/scenario-unity-uiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/critique.mdexpert-notes.mdgui-paths.mdprocedures.mdsources.mdscripts/AgentKit/UI/UIAudit.csUIBuild.csUICapture.csUIPerf.csUISetup.csUIToolkitBuild.csscripts/Runtime/UI/AgentUI.Runtime.asmdefCanvasDeviceScale.csClampedWidth.csHudBar.csHudModel.csHudView.csMenuRouter.csMenuScreen.csPanelChangeLog.csRebindRow.csRebuildProbe.csScrollToSelection.csSelectableFeedback.csSettingsScreen.csSettingsService.csUiCounterSampler.csUILoader.csUiPerfDriver.csUiTheme.cs詳細
Unity UI(UI開発者)
優れた UI とは、縦向きのスマートフォンから 4K モニターまで同じ形を保ち、マウス、タッチ、キーボード、ゲームパッドのどれにも応答し、読みやすく、静止している間のコストがほとんどかからない画面です。エージェントは、コードまたはテキストから構築し、あらゆるデバイスサイズで各画面をキャプチャし、同じフレームでレイアウトをアサートし、監査、動作テスト、カウンターで検証することで、これを実現します。対象:Unity 6000.3.21f1、uGUI 2.0(内部で TextMeshPro を使用)、UI Toolkit、Input System 1.20。このスキルで名前が挙がっている関連スキルが利用可能なスキルにない場合は、ユーザーにインストールを依頼してください(npx skills add scenario-labs/skills --skill <name>)。無人で進める場合は、ツールのスキーマを基に作業を続け、不足している点を明示してください。
必須の背景知識: scenario-unity-expert(チャネル、レビューサイクル、6.3 の落とし穴)。ツールキット:
scripts/ut_ui.py(ut_env、ut_run、ut_review をインポート)、ジョブは
scripts/AgentKit/UI/、ランタイムコンポーネントは
scripts/Runtime/UI/(asmdef AgentUI.Runtime)、UXML/USS/TSS テンプレートは
scripts/templates/uitk/ にあります。
基本姿勢(エキスパートならではの違い)
- 6.3 のランタイムでは引き続き uGUI が推奨されています。選択はマトリックスで判断します。 UI Toolkit のみ:データバインディング、USS トランジション、柔軟なレイアウト、グローバルスタイル、ダイナミックアトラス、RTL と絵文字、SVG。uGUI のみ:アニメーションクリップと Timeline、シリアル化イベント、Scene ビューでのオーサリング(6.3 Manual)。カスタムシェーダー(UI Shader Graph)とワールドスペースは 6.3 では BOTH 列に含まれます。uGUI を選ぶ理由にはなりません。阻害要因がなければ、プロジェクトで採用済みのシステムを維持します。UI が中心のプロジェクトやデザイナー主導のプロジェクトでは UI Toolkit を優先し、両列の機能が必要な場合は画面ごとに使い分けます(
ut_ui.choose_system)。 - 基準解像度は 1 つにし、端をアンカーし、向きに合わせて Match を選びます。 1920 x 1080、Scale With Screen Size、両方の向きに対応する場合は Match 0.5 にします。この横向きの基準解像度では、Match 0 にすると縦向きのスマートフォンは 0.5625 倍に縮小されます(Match 1 では 1.78 倍に拡大されます)。マニュアルにある「Match 0 で 1.5 倍」は、縦向きの基準解像度を横向きで表示した場合の値です。uGUI は Match を対数空間で補間し、UI Toolkit は線形補間します。1080 x 1920 では、それぞれ 1.0 と 1.17 になります(実測)。Game ビューにデザイン解像度を表示した状態で各要素を隅にアンカーし、スケールは 1 のままにします(uGUI manual;Christina)。タッチターゲットを確認して設定したハンドヘルド用倍率(
CanvasDeviceScale、1.35)をスマートフォンに適用します。 - uGUI の Canvas は再構築とバッチの単位です。 静的コンテンツとフレームごとに変わるコンテンツはサブ Canvas に分割し、表示専用の Canvas から Raycaster を削除し、ラベルの Raycast Target のチェックを外します。Canvas 同士がバッチを共有することはありません。ワールドスペースのネームプレートが 400 個あれば、400 バッチになります(Andy Touch)。
Canvas.enabledで非表示にします(SetActiveの 200 回に対して、メッシュ再生成は 0 回。実測)。さらにCanvasGroup.interactableを設定しないと、ボタンを操作できる状態のままになります。 - レイアウトでは、preferred があればそれを、なければ min、さらにどちらもなければ 0 が使われます。 報告するサイズが何もない子要素は、Control Child Size の設定下で折りたたまれます。Content Size Fitter は最上位にのみ配置し、拡大方向はピボットで決めます。フレームごとに更新される UI にはレイアウトグループを使いません。サイズが予想と異なる場合は、チェックボックスを切り替えるのではなく、親と子の min/preferred/flexible を確認します(
UIAudit.ExplainLayout)(Christina、HTQV4mukZ2M)。 - 両システムを通じて、選択状態は 1 つ、レイヤーテーブルは 1 つにします。 ホバーで選択し、画面を表示した 1 フレーム後に最初の選択状態を設定します。ゲームパッド用には最後の選択状態を記憶します(Sasquatch B Studios)。スクリプトで使う
InputSystemUIInputModuleをInputSystem.actionsに割り当てます。そうしないと、再バインドがナビゲーションに反映されません(実測)。1 つのテーブル(ut_ui.UI_LAYERS:HUD 0、メニュー 10、モーダル 20)から、各レイヤーに固有のソート順を割り当てます。Canvas.sortingOrderとPanelSettings.sortingOrderは互いに順位を比較します(描画は 2021.2 以降、Unity スタッフによる確認;入力はここで実測)。同じ値の場合、最上位のレイヤーは Hierarchy の順序で決まります(Christina)。EventSystem を介してシステム間でフォーカスを移します。element.Focus()でパネルを選択すると、SetSelectedGameObject(uguiButton)でフォーカスが外れます(実測)。UI は専用の Additive Scene に配置し、EventSystem はそこに 1 つだけ置きます(Jason Weimann)。 - テキスト:エフェクトはマテリアルで処理し、システムごとにフォントチェーンを 1 つ用意します。 Shadow と Outline を重ねると、三角形の数は 28 から 280 に増えました。TMP のアウトラインとアンダーレイでは 30 のままでした(実測;Andy Touch)。TMP のフォールバックは UI Toolkit のテキストには適用されません。UI Toolkit は独自のフォントと Panel Text Settings を使用します。TMP Settings に CJK フォントを設定しても、HUD では「設定」が表示されませんでした(実測)。各システムで、すべてのロケールに対して
tryAddをオンにして確認します。すべてのフォールバックアセットでサンプリングサイズとパディング(約 10 分の 1)を揃え、CJK は複数のアセットに分割します。RTL が必要なら UI Toolkit を使います(Imphenzia)。コードで項目を設定するドロップダウンは、ロケールイベント時に再生成します(SettingsScreen.OnLocaleChanged)。 - UI Toolkit のコストは GPU の状態と非表示にしている時間に左右されます。 バッチあたりのテクスチャは最大 8 個です(実測値は ceil(N/8))。静的パネルを頂点バッファーに分割すると、描画は 2 回になります。Vertex Budget を増やします(頂点数 12k の場合、0 では 3 バッチ、20000 では 1 バッチ。実測)。ステンシルマスクはバッチを分割するため、円形のミニマップフレームは事前に切り抜きます。使用ヒントを指定して Transform をアニメーション化し、大きなコンテナーではクラスを切り替えません。
[GeneratePropertyBag]はアセンブリ属性も設定した場合にのみ機能します(クラスだけの場合はリフレクションによるバッグが生成されました。実測)(Nicolas Borromeo、Unity)。非表示にする期間に応じて方法を選びます。長時間表示しない場合は削除し、その間は display none を使います(バインディングは動作し続けます)。点滅には opacity または画面外への移動を使います(ut_ui.uitk_hide_method、コストは手順 P16)。PanelChangeLogでアイドル時の無効化を見つけます。スタイルシートは参照先のアセットをすべて読み込みます。 - 実際の描画方法で UI をキャプチャし、同じフレームでアサートします。 Overlay Canvas はカメラのターゲットに描画されません(UI ピクセル 0。実測)。uGUI は非表示のカメラで Screen Space Camera を使い、UI Toolkit は
targetTextureを設定した PanelSettings のクローンを使ってキャプチャします。4K の切り抜きを含め、すべてのシートを確認します。
最初に確認すること
プラットフォームと向き、入力方式、言語(CJK、RTL)と各文字列を描画するシステム、後から UI を編集する担当者、すでに使用しているシステム、デバイス一覧(デフォルト:縦向きのスマートフォン 1080 x 1920、420 dpi、ノート PC 1920 x 1080、4K)、配色(デフォルト:フラットなニュートラルカラーにアクセントカラーを 1 色)、レベル間で共有する UI シーン、予算(デフォルト:アイドル状態の HUD による GC なし、1 バッチ、フレームあたりのパネル変更 0 回)。
ワークフロー
- システムを選定する。
ut_ui.choose_system(needs, ui_heavy, existing, team)。GATE:ブロッカーを引用し、共有行を理由に使わず、両方のシステムを出荷する場合はレイヤーテーブルを用意します。 - セットアップする。
UISetup.ImportTmpEssentials、UISetup.AddScenesToBuild、ut_ui.add_ui_test_framework。ミキサーは scenario-unity-gameplay を使用します。GATE:TMP Settings が存在すること。 - 構築する。
UiThemeトークン(8 px 単位、アクセントカラー 1 色、タイトルレベル 1 つ。Game Dev Guide)。uGUI:UIBuild.BuildMenuSceneまたはそのヘルパーを使用します。UI Toolkit:ut_ui.write_uitk_templatesの後にUIToolkitBuild.BuildHudを実行します。GATE:コンパイルエラーと警告が 0 件、各シートのルールが 0 より多い状態でImportReportのエラーが 0 件、lint_uss/lint_uxml/lint_cs_events/lint_cs_queriesがクリーンであること。 - キャプチャして検証する。 実際のレベル上で HUD を含め、
ut_ui.shots(...)に対してUICapture.CaptureUGUI/CaptureUITKを実行します。GATE:layout_verdictが空であること、スケールが数式と一致すること、シートと 4K のクロップを確認して批評すること(references/critique.md)。レイアウトの崩れはExplainLayoutで説明します。 - 監査する。 すべてのロケールの文字列を指定して
UIAudit.Auditを実行します。UI Toolkit のテキストにはUIToolkitBuild.UitkGlyphs、データソースにはBindingSourcesを使用します。GATE:両方のシステムでエラー 0 件、警告 0 件、欠落グリフ 0 件、すべてのソースが生成済みであること。 - 動作を確認する。 Play Mode テスト(選択、ゲームパッド、非表示画面、設定、再バインド、加算シーン、バインディング、レイヤーとフォーカス、ロケール)と Edit Mode UI Test Framework テスト(クリック、キー、バインディング、クエリされた名前)を実施します。GATE:すべて合格すること。
- コストを確認する。
UIPerf.HideCost、TextEffectCost、PlayModeCounters(カウンター、list_markers)、PanelChangeLogを確認します。GATE:変更ごとに、変更前と変更後の数値を予算と照合すること。 - 納品する。 Verified と Assumed、および以下の引き継ぎ資料を添えます。
数値
| 値 | 比較対象 | 出典 |
|---|---|---|
| 1920 x 1080、Match 0.5 | 基準、両方の向き | uGUI manual;Christina |
| 1.0 / 2.0;Match 0 で 0.5625 | 1080 x 1920 / 3840 x 2160 での uGUI のスケール | measured;formula |
| 1.1701 / 1.4769 | 1080 x 1920 / 1170 x 2532 での UI Toolkit のスケール(uGUI は 1.0 / 1.1953) | measured |
| 基準 88 px x 1.35 = 119 px | 420 dpi での 116 px(7 mm)の目標に対するコントロールの高さ | [added] |
| 4.5:1 / 3:1 | コントラスト、本文 / 大きな文字 | [added] WCAG |
| 8;256 px | UI Toolkit のバッチあたりのテクスチャ数(実測);デモでの動的アトラスサイズフィルター | Borromeo |
| 3 対 1 バッチ | 12,000 頂点、Vertex Budget 0 対 20000 | measured |
| 7 / 18 ms | ステンシルのネストレベル数 / 1 つの大きなクラス切り替えによる Update Style | Borromeo |
| 0.87-0.99 / 0.005 ms | フレームごとの非表示のバインド済み画面:display none / 削除(表示時は 1.16-1.32) | measured, 3 runs |
| 2.2-3.3 ms | 削除した 120 行の画面の再追加(display flex は 1.5-2.0) | measured, 3 runs |
| 0 対 200 | メッシュの再生成数:Canvas.enabled 対 SetActive、200 個のグラフィック | measured |
| 40 から 14 | Sprite Atlas 適用後のバッチ数(回転、タイトパッキング無効) | Andy Touch |
| 0.01、100 px = 1 unit | ワールド空間キャンバスのスケール | Christina, Brackeys |
| 80 / 8 | TMP のサンプリングポイントサイズ / パディング | Imphenzia |
品質ゲート
- 測定可能: コンパイルエラーなし;すべてのデバイスで
layout_verdictが空;スケールがcanvas_scaleまたはpanel_scaleと一致;UIAuditのエラー 0 件、警告 0 件(ソートの同順位、ワールドキャンバス、静的マスク、 中央アンカーのエッジ、アトラス設定を含む);TMP と UI Toolkit でグリフの欠落が 0 件;USS ルールを維持;Play Mode テストと Edit Mode テストの失敗 0 件;静的パネルは 1 バッチ;アイドル状態の HUD は GC 0 件、パネルの変更 0 件。 - 視覚: コンタクトシートと 4K の切り抜きを、階層、配色、コントラスト、間隔、すべてのサイズで同じ形状であること、レベル上で HUD が読みやすいことに基づいて評価します。
よくある間違い
| 間違い | 状況 | 修正方法 |
|---|---|---|
| カメラで Overlay UI をキャプチャする | UI のないフレーム | CaptureUGUI |
| 横向きの参照画像で Match を 0 にする | 縦向き UI が 0.56 倍になる | Match を 0.5 にするか、向きごとにキャンバスを用意する |
| UI Toolkit で同じ Match を使う | 縦向きの HUD が 17% 大きくなる | panel_scale |
| カスタムシェーダーを uGUI に割り当てる | 2022 年当時の古いアドバイス | UI Toolkit 用の UI Shader Graph(6.3) |
| 1 つの描画順に 2 つのレイヤーを配置する | ポーズメニューが HUD の下に表示され、クリックが誤ったシステムに届く | テーブルを 1 つにし、異なる値を割り当てる |
| フォーカスが別のシステムに残る | UI Toolkit 上に uGUI のポップアップを表示すると、ゲームパッドが反応しなくなる | 表示時に SetSelectedGameObject、戻るときに element.Focus() |
| 画面隅の UI に中央アンカーを使う | 21:9 でカウンターが画面外にずれる | 画面隅用のアンカーを使う |
| SetActive / Canvas.enabled だけで非表示にする | 再構築の急増 / 非表示のボタンを操作できる | MenuScreen.Show |
| Control Child Size の下に空の子要素がある | 要素が消える | Layout Element の下限値を設定する。ExplainLayout |
| 敵のバーごとにキャンバスを 1 つ作る | 敵が増えるとバッチ数が増える | 共有キャンバス、UI Toolkit のワールド空間、スプライトを使う |
ミニマップに角丸の overflow: hidden や Mask を使う | マスクごとにバッチが分割される | フレーム画像を事前に切り抜く。シェーダーでクリップする |
| UI でアトラスの回転やタイトパッキングを使う | アイコンが上下逆になる、またはにじむ | 両方のチェックを外す |
| UI Toolkit で TMP フォールバックを期待する | HUD で文字が豆腐になる | Panel Text Settings のフォールバック、UitkGlyphs を使う |
| ドロップダウンの内容をコードで入力する | ロケールを切り替えても英語のままになる | ロケールイベントで再設定する |
クラスのみに [GeneratePropertyBag] を指定する | リフレクションバインディングが使われる | [assembly: GeneratePropertyBagsForAssembly] も指定する |
| 数分間非表示にする画面に display none を使う | バインディングのコストが発生し続ける | RemoveFromHierarchy |
| USS のエラーが 1 つある | シート全体が破棄され、UI のスタイルが適用されない | ImportReport のルール数を 0 より大きくする |
| Frame Debugger を合否判定に使う | エージェントが読み取れるものがない | Render/Batches Count レコーダーを使う |
| 最初の選択項目がない。デフォルトの UI アクションを使う | キーボードが反応しない。再バインドが無視される | MenuScreen.FirstSelected、InputSystem.actions |
| 登録解除せずに購読する | リロードのたびにハンドラーが蓄積する | OnDisable/OnDestroy で登録し、初期化し、-= する |
引き継ぎ
- 受け取るもの:scenario-unity-architecture からモデル、イベント、Input アクションアセットを受け取ります。scenario-unity-gameplay からは、MasterVol/MusicVol/SFXVol が公開された AudioMixer を受け取ります。scenario-unity-rendering-lighting からは品質レベルを受け取ります(実行時の
QualitySettings.namesに一覧表示されるのはプラットフォームのレベルのみです)。アーティスト、scenario-unity-2d、または scenario-* スキルからはスプライトとアイコンを受け取ります(アトラス化済み、回転とタイトパッキングは無効)。 - 引き渡すもの:scenario-unity-mobile にはセーフエリアパネル用のシステムごとのルートを引き渡します(UI Toolkit:y 軸を反転した
RuntimePanelUtils.ScreenToPanel)。scenario-unity-performance にはカウンター CSV を引き渡します。scenario-unity-shaders には UI Shader Graph または Canvas マテリアル(ミニマップのクリップ、ぼかし)を引き渡します。scenario-unity-pipeline-automation には CI 用の UI シーン、Play Mode テスト、Edit Mode テストを引き渡します。パケット:シーン、判定を記載したキャプチャシート、監査 JSON、テスト集計、検証済み項目と想定事項。
Unity 6.3 の注意点
- TextMeshPro は
com.unity.ugui2.0 に同梱されています。バッチモードではTMP_PackageResourceImporterがパッケージパスを見つけられません(UISetup.ImportTmpEssentials)。enableWordWrappingは非推奨です。 UnityEngine.UIとUnityEngine.UIElementsをusingすると、Image、Button、Sliderが曖昧になります(CS0104)。エイリアスを設定してください。- ランタイムバインディングは 6000.0 から、ワールドスペースの UI Toolkit は 6.2 から利用できます。6.3 では UI Shader Graph、USS の
filter、aspect-ratio、SVG、UI Test Framework パッケージ(com.unity.ui.test-framework6.3.0、組み込み)、より厳格な USS パーサーが追加されました。パーサーでエラーが発生すると、importedWithErrorsが設定された EMPTY StyleSheet が生成されます(実測済み)。PanelSettings.vertexBudget、textureSlotCount、SetPanelChangeReceiverは公開されています。マーカー:Scripts/UIElements.UpdateRuntimeBindings、.UpdateLayout、.UpdateStyle。 EditorSceneManager.NewSceneは参照されていないアセットをアンロードします。UXML を読み込む前にシーンを作成してください。- 6.3 以降:6.5 では Panel Renderer が UIDocument に置き換わります(UIDocument も引き続き動作します)。uGUI Raycast Receiver も追加されます。6.6 では UXML Factory/Traits が削除されます(現在は
[UxmlElement])。
参考資料
references/procedures.md:エージェント向けの手順 21 件。完全な呼び出し、実環境でのテスト、記録済みの結果を掲載しています。references/expert-notes.md:タイムスタンプ付きの専門家による原則。実測に基づく主張にはその旨を明記しています。references/critique.md:レイアウト、見た目、動作、構造、コストの評価基準です。references/gui-paths.md:エディターのウィンドウとメニューから同じ作業を行う方法です。references/sources.md:認証情報、URL、最適なタイムスタンプを含むすべての情報源です。