{"id":"eaa88f25-503b-4174-b722-ca236a905d19","shortId":"vZ7fzS","kind":"skill","title":"unity-ui","tagline":"UI 開発・検査・自動テストワークフロー。uitree で構造把握→pytest E2E テスト生成→PlayMode テストに移植。\nUse for: \"UI確認\", \"UI Toolkit\", \"uGUI\", \"E2Eテスト\", \"UI操作\", \"uitree\", \"スクリーンショット\"","description":"# unity-ui\n\n> **PREREQUISITE:** `../unity-shared/SKILL.md`（Relay Server 経由で Unity Editor が起動/アクティブであること）\n>\n> skill 経由のコマンドは必ず `-i <instance>` を付ける (unity-shared #インスタンス指定)。\n>\n> uitree コマンドは Play Mode 中のみ動作する。必ず `u -i <instance> play` してから実行すること。\n\n## UI テストの種別\n\n| 種別 | 検証内容 | 手法 | スクショ |\n|------|---------|------|---------|\n| Functional | 操作→状態が正しいか | click → text で値検証 | 不要 |\n| Visual Regression | 外観が変わっていないか | screenshot → 画像比較 | 必要 |\n| Structural Snapshot | ツリー構造が変わっていないか | dump --json → diff | 不要 |\n| Smoke | 最低限動くか | click → console にエラーなし | 任意 |\n| Monkey | ランダム操作でクラッシュしないか | monkey → errors 確認 | 不要 |\n\n## UI システム判定\n\n| 手がかり | UI Toolkit | uGUI |\n|---------|-----------|------|\n| ファイル | `.uxml`, `.uss` | `.prefab` に Canvas |\n| コンポーネント | UIDocument | Canvas, RectTransform |\n\n## コマンドリファレンス\n\n要素の指定方法は2通り: ref ID (`ref_3`) または `-p <panel> -n <name>`。\n\n### 構造把握\n\n```bash\nu -i <instance> uitree dump                           # 全パネル一覧 (contextType: Player がゲーム側)\nu -i <instance> uitree dump -p \"PanelSettings\"        # パネルのツリー (各要素の ref/name/type/classes が見える)\nu -i <instance> uitree dump -p \"PanelSettings\" --json # JSON 出力 (snapshot用)\nu -i <instance> uitree query -p \"PanelSettings\" -t Button              # type で検索 (VisualElement ベースのボタンはヒットしない → -c で検索)\nu -i <instance> uitree query -p \"PanelSettings\" -n \"BtnStart\"          # name で検索\nu -i <instance> uitree query -p \"PanelSettings\" -c \"action-btn\"        # USS class で検索\nu -i <instance> uitree query -p \"PanelSettings\" -t Button -c \"primary\" # AND 条件\nu -i <instance> uitree inspect -p \"PanelSettings\" -n \"BtnStart\"        # 要素詳細\nu -i <instance> uitree inspect ref_5_48                                # ref ID で指定\nu -i <instance> uitree inspect ref_5_48 --style                        # resolvedStyle 含む\nu -i <instance> uitree inspect ref_5_48 --children                     # 子要素情報含む\n```\n\n### テキスト取得\n\n```bash\nu -i <instance> uitree text -p \"PanelSettings\" -n \"ToastMessage\"  # name で指定\nu -i <instance> uitree text ref_5_12                               # ref ID で指定\n```\n\n### 操作\n\n```bash\nu -i <instance> uitree click -p \"PanelSettings\" -n \"BtnContinue\"  # name で指定\nu -i <instance> uitree click ref_5_48                              # ref ID で指定\nu -i <instance> uitree click ref_5_48 --count 2                    # ダブルクリック\nu -i <instance> uitree click ref_5_48 --button 1                   # 右クリック\nu -i <instance> uitree scroll -p \"PanelSettings\" -n \"ScrollArea\" --y 100\n```\n\n### モンキーテスト\n\n```bash\nu -i <instance> uitree monkey -p \"PanelSettings\" -c \"action-btn\" --count 50 --seed 42\nu -i <instance> uitree monkey -p \"PanelSettings\" --duration 30 --seed 42\nu -i <instance> uitree monkey -p \"PanelSettings\" -c \"action-btn\" --stop-on-error --json\n```\n\nquery でフィルタした要素をランダムに click し、コンソールエラーを監視する。\n`-c` (USS class) か `-t` (type) のフィルタが必須（フィルタなしでは要素が見つからない）。\n事前に `u -i <instance> uitree query -p <panel> -c <class>` で有効な class 名を確認してから monkey に渡す。\n`--seed` で操作順を再現可能。\n\n### スナップショット\n\n```bash\nu -i <instance> uitree snapshot save -p \"PanelSettings\" --name baseline    # 現在のツリーを保存\nu -i <instance> uitree snapshot diff -p \"PanelSettings\" --name baseline    # baseline との差分\nu -i <instance> uitree snapshot list                                        # 保存済み一覧\nu -i <instance> uitree snapshot delete --name baseline                      # 削除\n```\n\ndiff 出力: 要素の追加(`+`)/削除(`-`)/classes 変化(`~`) を検出。\n\n### スクリーンショット\n\n```bash\nu -i <instance> screenshot                          # GameView (-s game がデフォルト)\nu -i <instance> screenshot -p \"ui-check.png\"        # 保存先指定\nu -i <instance> screenshot --burst -n 5             # 連続 (アニメーション確認)\n```\n\nUI Toolkit / uGUI (Screen Space) は `-s game` でのみ映る。`-s camera` では映らない。\n\nGameView のキャプチャにはエディタのフォーカスが必要。タイムアウトする場合は再試行で解決することが多い。\n\n### uGUI の場合\n\nuitree は UI Toolkit 専用。uGUI は scene/component コマンドで操作する。\n\n```bash\nu -i <instance> scene hierarchy --depth 3\nu -i <instance> component list -t \"Canvas\"\nu -i <instance> component inspect -t \"MyButton\" -T \"UnityEngine.UI.Button\"\n```\n\n## 開発→テストフロー\n\n```text\nPhase 1: 作成 & 手動確認\n  コード変更 → /unity-verify → play → dump → 操作 → screenshot → stop\n\nPhase 2: pytest E2E テスト生成\n  dump で構造把握 → pytest テストファイルを生成 → 実行して確認\n\nPhase 3: PlayMode テスト移植\n  安定したシナリオを C# に書き直す → CI で回帰テスト\n```\n\n### Phase 1: 作成 & 手動確認\n\n```bash\nu -i <instance> play\nu -i <instance> uitree dump -p \"PanelSettings\"                 # 構造把握\nu -i <instance> uitree click -p \"PanelSettings\" -n \"BtnStart\"  # 操作\nu -i <instance> uitree text -p \"PanelSettings\" -n \"StatusLabel\" # 状態確認\nu -i <instance> screenshot                                      # 結果キャプチャ\nu -i <instance> stop\n```\n\n### Phase 2: pytest E2E テスト生成\n\nPhase 1 で確認した操作シナリオを、pytest テストとして永続化する。\nunity-cli の Python API (`UITreeAPI`, `ConsoleAPI`, `EditorAPI`) を直接使う。\n\n手順:\n1. `u -i <instance> play` + `u -i <instance> uitree dump` で構造を把握する\n2. 操作可能な要素（ボタン名、ラベル名）を特定する\n3. 以下のテンプレートに従い、`tests/integration/` にテストファイルを生成する\n4. `uv run python -m pytest tests/integration/<file> -v` で実行して確認する\n\nテンプレート:\n\n```python\n\"\"\"E2E tests for <UI名> — pytest + unity-cli API.\"\"\"\nimport time\nimport pytest\nfrom unity_cli.api import ConsoleAPI, EditorAPI, UITreeAPI\nfrom unity_cli.client import RelayConnection\n\nPANEL = \"<パネル名>\"  # u uitree dump で確認したパネル名\n\n\n@pytest.fixture(scope=\"module\")\ndef conn() -> RelayConnection:\n    conn = RelayConnection(instance=\"<プロジェクト名>\", timeout=5.0)\n    try:\n        EditorAPI(conn).get_state()\n    except Exception:\n        pytest.skip(\"Relay not available\")\n    return conn\n\n\n@pytest.fixture(scope=\"module\")\ndef uitree(conn: RelayConnection) -> UITreeAPI:\n    return UITreeAPI(conn)\n\n\n@pytest.fixture(scope=\"module\")\ndef console(conn: RelayConnection) -> ConsoleAPI:\n    return ConsoleAPI(conn)\n\n\n@pytest.fixture(scope=\"module\")\ndef editor(conn: RelayConnection) -> EditorAPI:\n    return EditorAPI(conn)\n\n\n@pytest.fixture(autouse=True)\ndef _play_mode(editor: EditorAPI):\n    \"\"\"Play Mode に入る。\"\"\"\n    state = editor.get_state()\n    if not state.get(\"isPlaying\"):\n        editor.play()\n        deadline = time.time() + 10\n        while time.time() < deadline:\n            if editor.get_state().get(\"isPlaying\"):\n                break\n            time.sleep(0.5)\n    yield\n\n\n@pytest.fixture(scope=\"module\", autouse=True)\ndef _stop_after_all(editor: EditorAPI):\n    \"\"\"全テスト後に Play Mode 終了。\"\"\"\n    yield\n    try:\n        editor.stop()\n    except Exception:\n        pass\n\n\n# --- Functional テスト ---\n\nclass TestMenuButtons:\n    def test_continue_shows_toast(self, uitree: UITreeAPI) -> None:\n        uitree.click(panel=PANEL, name=\"<ボタン名>\")\n        time.sleep(0.3)\n        result = uitree.text(panel=PANEL, name=\"<ラベル名>\")\n        assert result[\"text\"] == \"<期待値>\"\n\n\n# --- Smoke テスト ---\n\nclass TestSmoke:\n    BUTTONS = [\"<ボタン1>\", \"<ボタン2>\", ...]\n\n    def test_all_clickable_without_errors(self, uitree: UITreeAPI, console: ConsoleAPI) -> None:\n        console.clear()\n        for btn in self.BUTTONS:\n            uitree.click(panel=PANEL, name=btn)\n            time.sleep(0.2)\n        errors = console.get(types=[\"error\"])\n        assert errors.get(\"entries\", []) == []\n\n\n# --- Structural Snapshot ---\n\nclass TestStructure:\n    def test_tab_switch_changes_tree(self, uitree: UITreeAPI) -> None:\n        before = uitree.dump(panel=PANEL)\n        uitree.click(panel=PANEL, name=\"<タブ名>\")\n        time.sleep(0.3)\n        after = uitree.dump(panel=PANEL)\n        assert before != after\n```\n\n既存の `conftest.py` に `conn`, `uitree`, `editor`, `console` fixture がある場合はテンプレートの fixture 定義を省略し、conftest に委譲する。fixture の scope は conftest に合わせる（conftest が `session` なら `_play_mode` 等も同じ scope か互換性のある scope にする）。\n\n動的な値（タイムスタンプ、プログレス%等）を持つラベルは等値比較ではなくフォーマット検証を使う:\n```python\nassert result[\"text\"].endswith(\"%\")  # \"65%\" 等\n```\n\nテストの種別に応じてクラスを追加する:\n- `TestMenuButtons` — Functional (click → text 検証)\n- `TestSmoke` — 全ボタンクリック + エラーなし\n- `TestStructure` — ツリー構造の変化検出\n- `TestMonkey` — ランダム操作でエラーなし\n- `TestVisual` — screenshot 撮影（画像比較は手動 or 別ツール）\n\nMonkey テスト例:\n```python\nfrom unity_cli.api.uitree_monkey import MonkeyRunner\n\nclass TestMonkey:\n    def test_random_clicks_no_errors(self, uitree: UITreeAPI, console: ConsoleAPI) -> None:\n        # MonkeyRunner.run() は MonkeyResult を返す。errors は list[dict]\n        runner = MonkeyRunner(uitree, console)\n        result = runner.run(panel=PANEL, class_filter=\"<操作対象class>\", count=50, seed=42, interval=0.2)\n        assert result.errors == [], f\"Monkey errors: {result.errors}\"\n```\n\nSnapshot テスト例:\n```python\nfrom unity_cli.api.uitree_snapshot import SnapshotStore\n\nclass TestSnapshot:\n    def test_save_and_diff_no_changes(self, uitree: UITreeAPI, tmp_path) -> None:\n        store = SnapshotStore(snapshot_dir=tmp_path / \"snapshots\")\n        data = uitree.dump(panel=PANEL, format=\"json\")\n        store.save(\"baseline\", data)\n        current = uitree.dump(panel=PANEL, format=\"json\")\n        # diff(name, current): name は保存済みスナップショット名、current は比較対象のツリーデータ\n        result = store.diff(\"baseline\", current)\n        assert result[\"added\"] == []\n        assert result[\"removed\"] == []\n        assert result[\"changed\"] == []\n```\n\nmonkey テストの前にUIを初期状態に戻す（前のテストの副作用で Toast 等のクラスが変わることがある）。`time.sleep(2)` で Toast の hidden 復帰を待つか、テスト順序に依存しない assertion を使う。\n\n### Phase 3: PlayMode テスト移植\n\nPhase 2 の pytest で安定したシナリオを C# PlayMode テストに書き直す。\n\nPlayMode に移植する基準:\n- CI で毎回回す回帰テスト\n- フレーム精度が必要 (アニメーション完了待ち等)\n- Assert で厳密に状態検証\n- InputSystem / EventSystem 経由の操作\n\npytest E2E のまま残す基準:\n- 探索的テスト (シナリオが毎回変わる)\n- AI エージェントの自律テスト\n- Unity 外からの結合テスト\n\n手順:\n1. Phase 2 の pytest テストから安定したシナリオを選ぶ\n2. 以下のテンプレートに従い、`Assets/Tests/PlayMode/` に C# テストを生成する\n3. asmdef に UI コントローラの参照を追加する（必要に応じて）\n4. `u -i <instance> tests run play` で実行して確認する\n\nテンプレート:\n\n```csharp\nusing System.Collections;\nusing NUnit.Framework;\nusing UnityEngine;\nusing UnityEngine.TestTools;\nusing UnityEngine.UIElements;\n\nnamespace Game.Tests.PlayMode\n{\n    [TestFixture]\n    public class <UI名>Tests\n    {\n        private GameObject _hudObject;\n        private UIDocument _uiDocument;\n        private VisualElement _root;\n\n        [UnitySetUp]\n        public IEnumerator SetUp()\n        {\n            // UIDocument を持つ GameObject を生成\n            // コントローラが Awake/OnEnable で初期化するのを待つ\n            _hudObject = new GameObject(\"TestHUD\");\n            _hudObject.AddComponent<<コントローラ名>>();\n            _uiDocument = _hudObject.GetComponent<UIDocument>();\n\n            // コルーチン初期化 (StartCoroutine in OnEnable 等) は1フレームでは完了しない\n            // 2フレーム以上待つ\n            yield return null;\n            yield return null;\n\n            _root = _uiDocument.rootVisualElement;\n            Assert.IsNotNull(_root, \"Root visual element should be initialized\");\n        }\n\n        [TearDown]\n        public void TearDown()\n        {\n            Object.Destroy(_hudObject);\n        }\n\n        // --- Functional テスト ---\n\n        [UnityTest]\n        public IEnumerator <ボタン名>_Shows<期待される動作>()\n        {\n            var btn = _root.Q(\"<ボタン名>\");\n            Assert.IsNotNull(btn);\n\n            Click(btn);\n            yield return null;\n\n            var label = _root.Q<Label>(\"<ラベル名>\");\n            Assert.AreEqual(\"<期待値>\", label.text);\n        }\n\n        // --- Smoke テスト ---\n\n        [UnityTest]\n        public IEnumerator AllButtons_ClickableWithoutErrors()\n        {\n            var buttons = new[] { \"<ボタン1>\", \"<ボタン2>\", ... };\n\n            foreach (var name in buttons)\n            {\n                var element = _root.Q(name);\n                Assert.IsNotNull(element, $\"{name} should exist\");\n                Click(element);\n                yield return null;\n            }\n\n            LogAssert.NoUnexpectedReceived();\n        }\n\n        // --- ヘルパー ---\n\n        private static void Click(VisualElement element)\n        {\n            using var evt = ClickEvent.GetPooled();\n            evt.target = element;\n            element.panel.visualTree.SendEvent(evt);\n        }\n    }\n}\n```\n\nClick ヘルパーの注意:\n- `ClickEvent.GetPooled()` で座標計算不要のイベントを生成し、`panel.visualTree.SendEvent` で発火する\n- `NavigationSubmitEvent` では `RegisterCallback<ClickEvent>` が反応しないため使わない\n- ホバーやプレスエフェクトも再現したい場合は `PointerDownEvent` + `PointerUpEvent` を `worldBound.center` 座標付きで送る\n\nasmdef の注意:\n- テスト対象クラスが `Assembly-CSharp`（asmdef なし）にある場合、テスト asmdef からは直接参照できない\n- 対象クラスに専用 asmdef を作成し、テスト asmdef の `references` に追加する\n- 例: `Assets/UI/Game.UI.asmdef` を作成 → `Game.Tests.PlayMode.asmdef` の references に `\"Game.UI\"` を追加\n\nPhase 2 の pytest テストの各テストメソッドを1対1で C# に移植する。\n\n移植後は `u -i <instance> tests run play` で実行。\n\n## CLI 非対応操作\n\nunity-shared のフォールバック順に従う:\n1. `u api schema --type <Type>` で対応メソッドを検索\n2. `u api call` で実行\n3. 該当なしの場合のみ YAML 直接編集","tags":["unity","cli","bigdra50","agent-skills","developer-tools","python","unity3d"],"capabilities":["skill","source-bigdra50","skill-unity-ui","topic-agent-skills","topic-cli","topic-developer-tools","topic-python","topic-unity","topic-unity3d"],"categories":["unity-cli"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/bigdra50/unity-cli/unity-ui","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add bigdra50/unity-cli","source_repo":"https://github.com/bigdra50/unity-cli","install_from":"skills.sh"}},"qualityScore":"0.468","qualityRationale":"deterministic score 0.47 from registry signals: · indexed on github topic:agent-skills · 37 github stars · SKILL.md body (12,455 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:58:31.846Z","embedding":null,"createdAt":"2026-04-28T06:56:42.519Z","updatedAt":"2026-05-18T18:58:31.846Z","lastSeenAt":"2026-05-18T18:58:31.846Z","tsv":"'/classes':418 '/unity-shared/skill.md':29 '/unity-verify':499 '0.2':815,962 '0.3':774,847 '0.5':732 '1':297,495,525,570,585,1082,1320 '10':721 '100':308 '12':253 '2':287,506,565,594,1040,1054,1084,1088,1301,1326 '2フレーム以上待つ':1159 '3':114,476,516,599,1050,1094,1331 '30':332 '4':603,1100 '42':324,334,960 '48':212,222,232,275,285,295 '5':211,221,231,252,274,284,294,441 '5.0':653 '50':322,958 '65':895 'action':180,319,343 'action-btn':179,318,342 'ad':1027 'ai':1077 'allbutton':1213 'api':579,621,1322,1328 'asmdef':1095,1271,1277,1281,1284,1287 'assembl':1275 'assembly-csharp':1274 'assert':781,820,852,891,963,1025,1028,1031,1047,1067 'assert.areequal':1205 'assert.isnotnull':1168,1194,1229 'assets/tests/playmode':1090 'assets/ui/game.ui.asmdef':1292 'autous':701,737 'avail':664 'awake/onenable':1143 'baselin':387,397,398,412,1006,1023 'bash':119,236,258,310,378,422,470,528 'break':730 'btn':181,320,344,806,813,1191,1195,1197 'btncontinu':266 'btnstart':169,204,546 'burst':439 'button':155,192,296,789,1216,1224 'c':160,178,193,317,341,355,369,520,1058,1092,1305 'call':1329 'camera':454 'canva':104,107,482 'chang':831,985,1033 'children':233 'ci':522,1063 'class':183,357,371,757,787,825,924,954,977,1123 'cli':576,620,1314 'click':64,83,262,272,282,292,352,542,900,929,1196,1234,1244,1255 'clickabl':795 'clickablewithouterror':1214 'clickevent.getpooled':1250,1257 'compon':479,485 'conftest':866,872,874 'conftest.py':856 'conn':646,648,656,666,672,677,683,688,694,699,858 'consol':84,682,801,861,935,949 'console.clear':804 'console.get':817 'consoleapi':581,629,685,687,802,936 'contexttyp':125 'continu':761 'count':286,321,957 'csharp':1108,1276 'current':1008,1016,1019,1024 'data':999,1007 'deadlin':719,724 'def':645,670,681,692,703,739,759,792,827,926,979 'delet':410 'depth':475 'dict':945 'diff':79,393,414,983,1014 'dir':995 'dump':77,123,131,141,501,510,535,592,640 'durat':331 'e2e':11,508,567,614,1073 'e2eテスト':21 'editor':34,693,706,743,860 'editor.get':712,726 'editor.play':718 'editor.stop':751 'editorapi':582,630,655,696,698,707,744 'element':1172,1226,1230,1235,1246,1252 'element.panel.visualtree.sendevent':1253 'endswith':894 'entri':822 'error':90,348,797,816,819,931,942,967 'errors.get':821 'eventsystem':1070 'evt':1249,1254 'evt.target':1251 'except':659,660,752,753 'exist':1233 'f':965 'filter':955 'fixtur':862,864,868 'foreach':1220 'format':1003,1012 'function':61,755,899,1182 'game':428,451 'game.tests.playmode':1120 'game.tests.playmode.asmdef':1294 'game.ui':1298 'gameobject':1126,1140,1147 'gameview':426,456 'get':657,728 'hidden':1044 'hierarchi':474 'hudobject':1127,1145,1181 'hudobject.addcomponent':1149 'hudobject.getcomponent':1152 'id':112,214,255,277 'ienumer':1136,1186,1212 'import':622,624,628,634,922,975 'initi':1175 'inputsystem':1069 'inspect':200,209,219,229,486 'instanc':650 'interv':961 'isplay':717,729 'json':78,144,145,349,1004,1013 'label':1202 'label.text':1207 'list':404,480,944 'logassert.nounexpectedreceived':1239 'm':607 'mode':48,705,709,747,879 'modul':644,669,680,691,736 'monkey':87,89,314,328,338,373,916,921,966,1034 'monkeyresult':940 'monkeyrunn':923,947 'monkeyrunner.run':938 'mybutton':488 'n':117,168,203,243,265,305,440,545,554 'name':170,245,267,386,396,411,771,779,812,844,1015,1017,1222,1228,1231 'namespac':1119 'navigationsubmitev':1261 'new':1146,1217 'none':767,803,836,937,991 'null':1162,1165,1200,1238 'nunit.framework':1112 'object.destroy':1180 'onen':1156 'p':116,132,142,152,166,176,189,201,241,263,303,315,329,339,368,384,394,433,536,543,552 'panel':636,769,770,777,778,810,811,839,840,842,843,850,851,952,953,1001,1002,1010,1011 'panel.visualtree.sendevent':1259 'panelset':133,143,153,167,177,190,202,242,264,304,316,330,340,385,395,537,544,553 'pass':754 'path':990,997 'phase':494,505,515,524,564,569,1049,1053,1083,1300 'play':47,53,500,531,588,704,708,746,878,1105,1312 'player':126 'playmod':13,517,1051,1059,1061 'pointerdownev':1266 'pointerupev':1267 'prefab':102 'prerequisit':28 'primari':194 'privat':1125,1128,1131,1241 'public':1122,1135,1177,1185,1211 'pytest':10,507,512,566,572,608,617,625,1056,1072,1086,1303 'pytest.fixture':642,667,678,689,700,734 'pytest.skip':661 'python':578,606,613,890,918,971 'queri':151,165,175,188,350,367 'random':928 'recttransform':108 'ref':111,113,210,213,220,230,251,254,273,276,283,293 'ref/name/type/classes':136 'refer':1289,1296 'registercallback':1263 'regress':69 'relay':30,662 'relayconnect':635,647,649,673,684,695 'remov':1030 'resolvedstyl':224 'result':775,782,892,950,1021,1026,1029,1032 'result.errors':964,968 'return':665,675,686,697,1161,1164,1199,1237 'root':1133,1166,1169,1170 'root.q':1192,1203,1227 'run':605,1104,1311 'runner':946 'runner.run':951 'save':383,981 'scene':473 'scene/component':468 'schema':1323 'scope':643,668,679,690,735,870,881,883 'screen':447 'screenshot':71,425,432,438,503,559,911 'scroll':302 'scrollarea':306 'seed':323,333,375,959 'self':764,798,833,932,986 'self.buttons':808 'server':31 'session':876 'setup':1137 'share':43,1318 'show':762,1188 'skill':37 'skill-unity-ui' 'smoke':81,785,1208 'snapshot':75,382,392,403,409,824,969,974,994,998 'snapshotstor':976,993 'snapshot用':147 'source-bigdra50' 'space':448 'startcoroutin':1154 'state':658,711,713,727 'state.get':716 'static':1242 'statuslabel':555 'stop':346,504,563,740 'stop-on-error':345 'store':992 'store.diff':1022 'store.save':1005 'structur':74,823 'style':223 'switch':830 'system.collections':1110 'tab':829 'teardown':1176,1179 'test':615,760,793,828,927,980,1103,1124,1310 'testfixtur':1121 'testhud':1148 'testmenubutton':758,898 'testmonkey':908,925 'tests/integration':601,609 'testsmok':788,903 'testsnapshot':978 'teststructur':826,906 'testvisu':910 'text':65,240,250,493,551,783,893,901 'time':623 'time.sleep':731,773,814,846,1039 'time.time':720,723 'timeout':652 'tmp':989,996 'toast':763,1037,1042 'toastmessag':244 'toolkit':19,97,445,464 'topic-agent-skills' 'topic-cli' 'topic-developer-tools' 'topic-python' 'topic-unity' 'topic-unity3d' 'tree':832 'tri':654,750 'true':702,738 'type':156,360,818,1324 'u':51,120,128,138,148,162,172,185,197,206,216,226,237,247,259,269,279,289,299,311,325,335,364,379,389,400,406,423,430,436,471,477,483,529,532,539,548,557,561,586,589,638,1101,1308,1321,1327 'ugui':20,98,446,459,466 'ui':3,4,18,27,55,93,96,444,463,1097 'ui-check.png':434 'uidocu':106,1129,1130,1138,1151 'uidocument.rootvisualelement':1167 'uitre':8,23,45,122,130,140,150,164,174,187,199,208,218,228,239,249,261,271,281,291,301,313,327,337,366,381,391,402,408,461,534,541,550,591,639,671,765,799,834,859,933,948,987 'uitree.click':768,809,841 'uitree.dump':838,849,1000,1009 'uitree.text':776 'uitreeapi':580,631,674,676,766,800,835,934,988 'ui操作':22 'ui確認':17 'uniti':2,26,33,42,575,619,1079,1317 'unity-c':574,618 'unity-shar':41,1316 'unity-ui':1,25 'unity_cli.api':627 'unity_cli.api.uitree':920,973 'unity_cli.client':633 'unityengin':1114 'unityengine.testtools':1116 'unityengine.ui.button':490 'unityengine.uielements':1118 'unitysetup':1134 'unitytest':1184,1210 'use':15,1109,1111,1113,1115,1117,1247 'uss':101,182,356 'uv':604 'uxml':100 'v':610 'var':1190,1201,1215,1221,1225,1248 'visual':68,1171 'visualel':158,1132,1245 'void':1178,1243 'without':796 'worldbound.center':1269 'y':307 'yaml':1333 'yield':733,749,1160,1163,1198,1236 'か':358 'からは直接参照できない':1282 'か互換性のある':882 'が':875 'がある場合はテンプレートの':863 'がゲーム側':127 'がデフォルト':429 'が反応しないため使わない':1264 'が見える':137 'が起動':35 'し':353 'してから実行すること':54 'で':1041 'でのみ映る':452 'では':1262 'では映らない':455 'でフィルタした要素をランダムに':351 'で値検証':66 'で初期化するのを待つ':1144 'で厳密に状態検証':1068 'で回帰テスト':523 'で安定したシナリオを':1057 'で実行':1313,1330 'で実行して確認する':611,1106 'で対応メソッドを検索':1325 'で座標計算不要のイベントを生成し':1258 'で指定':215,246,256,268,278 'で操作順を再現可能':376 'で有効な':370 'で検索':157,161,171,184 'で構造を把握する':593 'で構造把握':9,511 'で毎回回す回帰テスト':1064 'で発火する':1260 'で確認したパネル名':641 'で確認した操作シナリオを':571 'との差分':399 'なし':1278 'なら':877 'に':103,857,1091,1096,1297 'にある場合':1279 'にする':884 'にエラーなし':85 'にテストファイルを生成する':602 'に入る':710 'に合わせる':873 'に委譲する':867 'に書き直す':521 'に渡す':374 'に移植する':1306 'に移植する基準':1062 'に追加する':1290 'の':577,869,1043,1055,1085,1288,1295,1302 'のまま残す基準':1074 'のキャプチャにはエディタのフォーカスが必要':457 'のフィルタが必須':361 'のフォールバック順に従う':1319 'の場合':460 'の注意':1272 'は':449,462,467,871,939,943 'は1フレームでは完了しない':1158 'は保存済みスナップショット名':1018 'は比較対象のツリーデータ':1020 'または':115 'を':1268 'を付ける':40 'を作成':1293 'を作成し':1285 'を使う':1048 'を持つ':1139 'を持つラベルは等値比較ではなくフォーマット検証を使う':889 'を検出':420 'を特定する':598 'を生成':1141 'を直接使う':583 'を返す':941 'を追加':1299 'アクティブであること':36 'アニメーション完了待ち等':1066 'アニメーション確認':443 'インスタンス指定':44 'エラーなし':905 'エージェントの自律テスト':1078 'コマンドで操作する':469 'コマンドは':46 'コマンドリファレンス':109 'コルーチン初期化':1153 'コンソールエラーを監視する':354 'コントローラが':1142 'コントローラの参照を追加する':1098 'コントローラ名':1150 'コンポーネント':105 'コード変更':498 'システム判定':94 'シナリオが毎回変わる':1076 'スクショ':60 'スクリーンショット':24,421 'スナップショット':377 'タイムアウトする場合は再試行で解決することが多い':458 'タイムスタンプ':886 'タブ名':845 'ダブルクリック':288 'ツリー構造が変わっていないか':76 'ツリー構造の変化検出':907 'テキスト取得':235 'テスト':756,786,1183,1209,1280,1286 'テストから安定したシナリオを選ぶ':1087 'テストとして永続化する':573 'テストに書き直す':1060 'テストに移植':14 'テストの前にuiを初期状態に戻す':1035 'テストの各テストメソッドを1対1で':1304 'テストの種別':56 'テストの種別に応じてクラスを追加する':897 'テストを生成する':1093 'テストファイルを生成':513 'テストフロー':492 'テスト例':917,970 'テスト対象クラスが':1273 'テスト生成':12,509,568 'テスト移植':518,1052 'テスト順序に依存しない':1046 'テンプレート':612,1107 'パネルのツリー':134 'パネル名':637 'ファイル':99 'フィルタなしでは要素が見つからない':362 'フレーム精度が必要':1065 'プログレス':887 'プロジェクト名':651 'ヘルパー':1240 'ヘルパーの注意':1256 'ベースのボタンはヒットしない':159 'ホバーやプレスエフェクトも再現したい場合は':1265 'ボタン1':790,1218 'ボタン2':791,1219 'ボタン名':596,772,1187,1193 'モンキーテスト':309 'ラベル名':597,780,1204 'ランダム操作でエラーなし':909 'ランダム操作でクラッシュしないか':88 '不要':67,80,92 '中のみ動作する':49 '事前に':363 '以下のテンプレートに従い':600,1089 '任意':86 '作成':496,526 '例':1291 '保存先指定':435 '保存済み一覧':405 '全テスト後に':745 '全パネル一覧':124 '全ボタンクリック':904 '出力':146,415 '別ツール':915 '削除':413,417 '前のテストの副作用で':1036 '動的な値':885 '右クリック':298 '各要素の':135 '名を確認してから':372 '含む':225 '変化':419 '外からの結合テスト':1080 '外観が変わっていないか':70 '子要素情報含む':234 '安定したシナリオを':519 '定義を省略し':865 '実行して確認':514 '対象クラスに専用':1283 '専用':465 '座標付きで送る':1270 '復帰を待つか':1045 '必ず':50 '必要':73 '必要に応じて':1099 '手がかり':95 '手動確認':497,527 '手法':59 '手順':584,1081 '探索的テスト':1075 '撮影':912 '操作':62,257,502,547 '操作可能な要素':595 '操作対象class':956 '既存の':855 '最低限動くか':82 '期待される動作':1189 '期待値':784,1206 '条件':196 '検査':6 '検証':902 '検証内容':58 '構造把握':118,538 '状態が正しいか':63 '状態確認':556 '現在のツリーを保存':388 '画像比較':72 '画像比較は手動':913 '直接編集':1334 '確認':91 '移植後は':1307 '種別':57 '等':888,896,1157 '等のクラスが変わることがある':1038 '等も同じ':880 '終了':748 '経由で':32 '経由のコマンドは必ず':38 '経由の操作':1071 '結果キャプチャ':560 '自動テストワークフロー':7 '要素の指定方法は2通り':110 '要素の追加':416 '要素詳細':205 '該当なしの場合のみ':1332 '連続':442 '開発':5,491 '非対応操作':1315","prices":[{"id":"407fb644-5652-4695-abd7-022c93b8b99b","listingId":"eaa88f25-503b-4174-b722-ca236a905d19","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"bigdra50","category":"unity-cli","install_from":"skills.sh"},"createdAt":"2026-04-28T06:56:42.519Z"}],"sources":[{"listingId":"eaa88f25-503b-4174-b722-ca236a905d19","source":"github","sourceId":"bigdra50/unity-cli/unity-ui","sourceUrl":"https://github.com/bigdra50/unity-cli/tree/main/skills/unity-ui","isPrimary":false,"firstSeenAt":"2026-04-28T06:56:42.519Z","lastSeenAt":"2026-05-18T18:58:31.846Z"}],"details":{"listingId":"eaa88f25-503b-4174-b722-ca236a905d19","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"bigdra50","slug":"unity-ui","github":{"repo":"bigdra50/unity-cli","stars":37,"topics":["agent-skills","cli","developer-tools","python","unity","unity3d"],"license":"mit","html_url":"https://github.com/bigdra50/unity-cli","pushed_at":"2026-05-12T01:15:17Z","description":"CLI tool for controlling Unity Editor via command line - Play Mode, console logs, tests, scenes, GameObjects and more","skill_md_sha":"e7e4812043b18fbfad66980d3c4659d189371754","skill_md_path":"skills/unity-ui/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/bigdra50/unity-cli/tree/main/skills/unity-ui"},"layout":"multi","source":"github","category":"unity-cli","frontmatter":{"name":"unity-ui","license":"MIT","description":"UI 開発・検査・自動テストワークフロー。uitree で構造把握→pytest E2E テスト生成→PlayMode テストに移植。\nUse for: \"UI確認\", \"UI Toolkit\", \"uGUI\", \"E2Eテスト\", \"UI操作\", \"uitree\", \"スクリーンショット\"","compatibility":"Requires `u` CLI (unity-cli) and active Unity Editor via Relay Server."},"skills_sh_url":"https://skills.sh/bigdra50/unity-cli/unity-ui"},"updatedAt":"2026-05-18T18:58:31.846Z"}}