ui-ugui について
ui-ugui は、Unity uGUI の理解、編集、生成を支援するスキルです。既存の階層を調べてから、不要な再構築を避け、対象を絞った変更を行い、結果を確認します。
主な機能
- 01Canvas と UI 階層を調査
- 02既存 UI を対象限定で編集
- 03Canvas ベースの階層を生成
- 04レイアウトと RectTransform のアンカーを設定
- 05表示状態とインタラクション設定を確認
活用シーン
- 01既存の Unity UI 構造を説明
- 02表示されない UI 要素やサイズ異常を修正
- 03メニューなどの Canvas レイアウトを作成
- 04画面全体を再構築せず特定コンポーネントを変更
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ unity-technologies/ skills --skill ui-uguiインストール後、Claude Code で/ui-uguiを入力して読み込まれたか確認します。
同梱ファイルreferences/scrollview-setup.md
詳細
既存の Unity uGUI を理解し、対象を絞って編集し、新しい Canvas ベースの階層を生成します。
ScrollRect/ScrollView を扱う場合は、次のリファレンスファイルを読んでください:
- references/scrollview-setup.md — 必須の階層、設定ルール、よくある失敗
対象範囲
ユーザーが何を求めているか判断します:
| リクエストの種類 | 対応 |
|---|---|
| UI に関する質問 | 理解 — 階層を分析し、構造を説明 |
| 特定の要素の変更 | 編集 — 対象を絞って変更するだけ |
| 新しい UI の作成 | 生成 — 新しい階層を作成 |
| 既存 UI の修正/改善 | 編集 — 既存のものを変更し、作り直さない |
依頼されたものだけを生成します:
| リクエスト | 出力 |
|---|---|
| UI レイアウト | Prefab またはシーン階層のみ |
| 「コード付き」/「ロジック付き」/「機能する」 | 階層 + スクリプト |
次の表現はスクリプトを意味しません:
- 「適切なボタン」→ 適切に設定された Button コンポーネント
- 「動作する UI」→ レンダリング可能な有効な階層
- 「メニュー画面」→ 視覚的なレイアウトのみ
重要なルール
名前空間の曖昧さの解消:
- UI コンポーネントを作成または参照する場合は、常に完全修飾型名を使用します
ImageではなくUnityEngine.UI.ImageButtonではなくUnityEngine.UI.Button- プロジェクト内のほかの名前空間が、型の曖昧性エラーを引き起こすことがあります
変更前に確認する:
- 変更を加える前に、現在の状態を必ず確認します
- 子を追加する前に、親オブジェクトが存在することを確認します
- プロパティを変更する前に、コンポーネントが存在することを確認します
- 階層の状態を決めつけず、まず確認します
作り直すより段階的に修正する:
- 問題を修正するときは、対象を絞って修正します
- 問題を解決するために階層全体を破棄して作り直すことはしません。オブジェクトを破棄すると、null 参照が連鎖的に発生することがあります
- 大きな部分を書き換えるのではなく、問題のある特定のプロパティを見つけて、それだけを修正します
- 修正に失敗した場合は、別の方法を試す前に変更を元に戻します
一度に一つの変更を行う:
- 変更を一つ行い、その結果を確認します
- 関連のない複数の変更をまとめて行いません
- 特定の要素を編集する際、隣接する要素を誤って変更または削除しないよう注意します
- 失敗した場合は、別の方法を試す前に原因を把握します
- 複数の変更を同時に行う「手当たり次第のデバッグ」は避けます
色と表示状態:
- テキストがデフォルトで読みやすいことを確認します: 色を選ぶときは、テキストと背景に十分なコントラストを確保します。ただし、無効状態、プレースホルダーテキスト、装飾要素など、意図的にコントラストを低くしている場合は尊重します
- 新しい要素の表示状態を確認します: UI 要素を作成した後、サイズがゼロではなく、親の範囲内にあることを確認します。後で切り替える、アニメーションさせるなどの目的で意図的に非表示にした要素は問題ありません
仕様の遵守:
- ユーザーの仕様を正確に守ります: ユーザーがピクセル単位の寸法、16 進数カラー、位置、間隔、その他の正確な値を指定した場合は、概算や代替ではなく、その値を正確に適用します
- 無関係な変更を最小限にします: 編集時は、修正に関連する調整が必要な場合を除き、ユーザーが指定していないプロパティの変更を避けます
規約
まずプロジェクトのパターンに従います。 デフォルト設定を適用する前に、既存のファイルを検索します。
| 種類 | 規約 | 良い例 | 悪い例 |
|---|---|---|---|
| GameObject 名 | PascalCase | SubmitButton | submit-button |
| Prefab のパス | 機能別フォルダー | Assets/UI/Inventory/ | Assets/Prefabs/UI/ |
ワークフロー
- 状態を確認 — 作業を始める前に、シーン/階層内に存在するものを確認します。
- 分析 — 必要なものを正確に判断します。余計なものは追加しません。
- 検索 — 既存の Prefab、Canvas、アセットを見つけます。パスを決めつけません。
- プロジェクトのパターンに従う — フォルダー構成と命名規則を合わせます。
- 作成または編集 — 適切なアンカーを設定して構造を構築するか、対象を絞って編集します。
- 結果を確認 — 次に進む前に、変更が反映されたことを確認します。
Canvas のセットアップ
すべての UI には Canvas が必要です。
Canvas (Screen Space - Overlay or Camera)
├── CanvasScaler (Scale With Screen Size recommended)
├── GraphicRaycaster
└── [UI Content]
CanvasScaler の設定:
- プロジェクトに「Constant Pixel Size」を使用する特別な理由(ピクセルアートや固定解像度のターゲットなど)がない限り、UI Scale Mode は「Scale With Screen Size」をデフォルトにします。
- Reference Resolution:プロジェクトの標準に合わせます(例:1920x1080)。
- Screen Space - Camera で Canvas を作成する場合は、まずカメラの Reference Resolution を確認します。
- Match Width Or Height:0.5(バランス型)
- 既存の Canvas が「Constant Pixel Size」を使用している場合は、その旨を伝え、変更する前にユーザーに確認します。
- レイアウトには、絶対的なピクセル位置よりもアンカーと Layout Group を優先します。
レイアウトコンポーネント
Layout Group は子要素のサイズを制御します:
- 親に Layout Group がある場合、子の RectTransform は親によって管理されます。
- 子のアンカーと sizeDelta は親によって上書きされる場合があります。
- 値を設定する前に、サイズを制御するのが親か子かを確認します。
Vertical/Horizontal Layout Groups:
- Control Child Size:親が子要素の寸法を設定するかどうかを指定します。
- Child Force Expand:子要素を引き伸ばして空間を埋めるかどうかを指定します。
- Control Child Size がオフの場合、子要素に明示的なサイズを設定する必要があります。
レイアウトの競合を避けるには:
- 親が子要素を制御している場合、子のアンカーやサイズを手動で設定しないでください。
- 固定サイズにする要素には Layout Group を追加しないでください。
- 入れ子になった Layout Group は、各階層を慎重に設定する必要があります。
- レイアウトが正しくない場合は、子を変更する前に親の設定を確認してください。
- Control Child Size が有効な Layout Group と同じオブジェクトに ContentSizeFitter を追加すると、競合します。
- 親の Control Child Size が有効な子に ContentSizeFitter を追加すると、ContentSizeFitter は上書きされ、無駄になります。
- Layout Group を持つ親と ContentSizeFitter を使用する場合は、対象の軸について親の Control Child Size を無効にします。
- 一般的なパターン:ScrollView の Content に ContentSizeFitter と VerticalLayoutGroup を設定します。VLG が子要素を制御し、ContentSizeFitter が Content 自体のサイズを設定します。
Grid Layout Group:
- インベントリのグリッドやカードのレイアウトに使用します。
- Cell Size は明示的に設定する必要があります。子要素のサイズはこれに合わせて設定されます。
- Constraint は行数や列数の上限を制御します。
Content Size Fitter:
- Horizontal/Vertical Fit:Preferred Size
- コンテンツに合わせてサイズを調整するコンテナーに使用します。
- 優先サイズを提供するレイアウト要素またはテキストコンポーネントが必要です。
RectTransform のアンカー設定
表示するには、要素のサイズがゼロ以外である必要があります:
- sizeDelta で幅と高さを明示的に設定する、または
- 適切なオフセットを設定してストレッチアンカーを使用する、または
- 親の Layout Group にサイズを制御させる(Control Child Size を有効にする)
アンカー設定の順序:
- まずアンカープリセット(角、辺、ストレッチ)を設定します。
- 次に位置やオフセットの値を設定します。
- 結果のサイズがゼロ以外であることを確認します。
一般的なパターン:
- ストレッチアンカー — 利用可能な領域を埋めるレスポンシブな要素向け
- 角アンカー — 位置とサイズが固定された要素向け
- 辺アンカー — 一方向にのみ伸縮する要素向け
自然言語による説明から位置を設定する場合: ユーザーが位置(例:「右上」「下部バー」「左側」)を説明した場合:
- それが角(固定位置)、辺(一方向に伸縮)、全面(両方向に伸縮)のどれに当たるかを判断します。
- anchor min と anchor max を設定します。角の場合は同じ位置にし、辺や全面の場合は範囲を指定します。
- アンカーポイントに合わせて pivot を設定します。pivot は、デフォルト(0.5, 0.5)のままにせず、要素がアンカーされる位置に合わせる必要があります。「右上」の要素なら右上の角、「上部バー」なら上辺の中央に pivot を設定します。
- アンカーと pivot を設定した後に、位置やオフセットの値を設定します。
表示状態のチェックリスト:
- 幅と高さがどちらもゼロより大きい
- 要素が親の範囲内にある
- 要素が兄弟要素に隠れていない(階層の順序を確認)
- Image コンポーネントにスプライトが設定されているか、アルファ値が 0 より大きい色が設定されている
共通コンポーネント
| コンポーネント | 用途 |
|---|---|
Image | 背景、アイコン |
RawImage | テクスチャ、動画の描画 |
Text (TMP) | すべてのテキスト(TextMeshPro を使用) |
Button | クリック可能な要素 |
Toggle | チェックボックス、ラジオボタン |
Slider | 値の範囲 |
ScrollRect | スクロール可能なコンテンツ |
InputField (TMP) | テキスト入力 |
ベストプラクティス
- すべてのテキストに TextMeshPro を使用してください(レガシーの Text は使用しないでください)
- テキストを含む WorldSpace UI でも Text Mesh Pro を使用してください。プロジェクトを確認し、TMP のエッセンシャルリソースがプロジェクトにない場合はインポートしてください
- TextMeshPro のエッセンシャルリソースをインポートした場合は、アセットのインポート後に TMP Importer ウィンドウと Import Unity Package ウィンドウを閉じてください
- 階層を論理的に整理してください(Header、Content、Footer)
- 可能な場合は、手動で配置する代わりに Layout Group を使用してください
- インタラクティブでない画像では Raycast Target = false に設定してください
- パフォーマンス向上のため、スプライトアトラスを使用してください
ユーザーがインタラクティブな TMP Essentials のインストールを求めている場合を除き、決して EditorApplication.ExecuteMenuItem("Window/TextMeshPro/Import TMP Essential Resources") を使用しないでください。モーダルダイアログが開き、ユーザーが閉じるまで呼び出し元の処理がブロックされます。
TMP リソースには AssetDatabase.ImportPackage() を使用しないでください。代わりに、非インタラクティブな正式 API である TMP_PackageResourceImporter.ImportResources() を使用してください。
インタラクションの準備
インタラクティブな要素を含む UI を完成させる前に、次の項目を確認してください。
- シーンに EventSystem が存在すること(ちょうど 1 つ)
- Canvas に GraphicRaycaster が設定されていること
- インタラクティブな要素では Raycast Target = true、ブロックを防ぐためインタラクティブでない要素では false に設定されていること
- Button.onClick が接続されていること(Inspector またはスクリプト経由)— スクリプトまたはロジックが求められている場合のみ
最初の 3 項目が欠けていると、インタラクティブな要素は見た目上存在していても、何も起きずに動作しません。
理解
既存の UI についてユーザーから質問された場合:
まず階層を確認してください。 推測せず、回答する前に必ずシーンまたはプレハブを確認してください。
構造を分析してください:
- Canvas とそのレンダーモードを特定する
- 親子関係を把握する
- どの Layout Group がどの子要素を制御しているかを特定する
- RectTransform のアンカー設定を確認する
次のような質問に回答してください:
- 「このボタンは何をしますか?」→ コンポーネント、階層内の位置、イベントの接続について説明する
- 「どのように配置されていますか?」→ Layout Group、アンカー、階層について説明する
- 「なぜ表示されないのですか?」→ サイズ、アンカー、親の範囲、コンポーネントの状態を確認する
- 「この要素のサイズは何で決まりますか?」→ Layout Group の設定またはアンカーをたどって確認する
編集
既存の UI に対象を絞った変更を加える場合:
編集前に確認してください。 必ず現在の状態を先に確認してください。
編集ワークフロー:
- 対象のオブジェクトが存在することを確認する
- 変更するプロパティまたはコンポーネントを特定する
- 必要最小限の変更を加える
- 次に進む前に結果を確認する
修正のために破棄してはいけません:
- オブジェクトを破棄すると、他の場所にある参照が連鎖的に null になります
- 作り直すのではなく、プロパティをその場で修正してください
- 要素を削除する必要がある場合は、先にすべての参照を更新してください
C#(依頼があった場合のみ)
- 名前空間の競合を避けるため、UI 型は完全修飾名で使用する
- Inspector の参照には
[SerializeField]を使用する - Awake() でコンポーネントの参照をキャッシュする
- ボタンのコールバックにはイベントまたはデリゲートを使用する
- スクリプトはプレハブと同じフォルダーに配置する(プロジェクトのパターンに従う)
コンポーネントの参照:
- 参照先のオブジェクトにアクセスする前に、存在することを確認する
- シリアライズされた参照が null の可能性がある場合に対処する
- 参照を接続するときは、対象のコンポーネントが存在することを確認する
エラーからの復旧
問題が発生した場合は、次の手順に従います。
停止して診断する:
- 正確なエラーまたは症状を特定します
- 修正を試みる前に、根本原因を突き止めます
- 推測に基づく変更は行いません
段階的に修正する:
- 一度に1つの問題に対処します
- 次に進む前に、各修正を検証します
- 変更した内容を記録しておきます
破壊的なパターンを避ける:
- 「最初からやり直す」方法では、壊れた要素だけでなく、正常に機能している要素も失われます
- 階層全体を再構築すると、問題の解決よりも新たな問題の発生につながります
- 全面的な置き換えではなく、必要な箇所だけを修正します
行き詰まった場合:
- 階層の現在の状態を改めて確認します
- 以前の変更が実際に適用されたかを確認します
- 実装ではなく、アプローチ自体が間違っていないかを検討します