Unity UIシステムとは

Unity UI(旧称uGUI)は、ゲーム内のユーザーインターフェースを作成するシステムです。

UIで作れるもの

  • 🎮 メインメニュー、ポーズ画面
  • 💯 スコア、HP表示(HUD)
  • 🔘 ボタン、スライダー
  • 💬 ダイアログ、チャット
  • 📊 インベントリ、ステータス画面

Canvas - UIの土台

Canvasの作成

Hierarchy > 右クリック > UI > Canvas

自動的に以下が作成される:
- Canvas
- EventSystem(入力管理)

Render Modeの種類

1. Screen Space - Overlay(推奨)

  • 画面に直接描画
  • ✅ 常に最前面
  • ✅ カメラ不要
  • 🎯 用途: HUD、メニュー

2. Screen Space - Camera

  • ✅ カメラの前に描画
  • ✅ カメラエフェクトが適用される
  • 🎯 用途: 特殊エフェクト付きUI

3. World Space

  • 3D空間に配置
  • ✅ オブジェクトの前後関係あり
  • 🎯 用途: 3D空間の看板、ヘルスバー

Canvas Scalerの設定

UI Scale Mode: Scale With Screen Size(推奨)
Reference Resolution: 1920 x 1080
Screen Match Mode: Match Width Or Height
Match: 0.5(中間)

これで画面サイズが変わってもUIが適切にスケールします。

Rect Transform

UIオブジェクトはTransformの代わりにRect Transformを使います。

Anchor(アンカー)

画面のどこに固定するかを決定します。

左上: X=0, Y=1
中央: X=0.5, Y=0.5
右下: X=1, Y=0

Shift+Altを押しながらアンカープリセットをクリック
→ 位置も同時に設定

主要なプロパティ

  • Anchors: 固定位置
  • Pivot: 回転・スケールの中心点
  • Position: アンカーからの相対位置
  • Width/Height: サイズ

Text(TextMeshPro推奨)

Textの作成

Hierarchy > 右クリック > UI > Text - TextMeshPro

初回は「Import TMP Essentials」をクリック

TextMeshProの設定

Text: 表示するテキスト
Font Asset: フォント
Font Size: サイズ
Color: 色
Alignment: 配置(左、中央、右)
Wrapping: 自動折り返し
Overflow: はみ出し処理

スクリプトから制御

using TMPro;

public class ScoreDisplay : MonoBehaviour
{
    public TextMeshProUGUI scoreText;
    private int score = 0;

    void Start()
    {
        UpdateScore();
    }

    public void AddScore(int points)
    {
        score += points;
        UpdateScore();
    }

    void UpdateScore()
    {
        scoreText.text = "Score: " + score.ToString();
    }
}

日本語フォントの設定

1. 日本語フォント(.ttf/.otf)をProjectにインポート
2. Window > TextMeshPro > Font Asset Creator
3. Source Font File: 日本語フォントを選択
4. Character Set: Unicode Range (Hex)
5. Character Sequence: 3000-30FF,4E00-9FFF(ひらがな、カタカナ、漢字)
6. Generate Font Atlas
7. Save

Button(ボタン)

Buttonの作成

Hierarchy > 右クリック > UI > Button - TextMeshPro

構成:
- Button (ボタン本体)
  └ Text (TMP) (ラベル)

Buttonの設定

// Inspectorで設定
Interactable: 有効/無効
Transition: 状態変化のエフェクト
  - Color Tint(色変化)
  - Sprite Swap(画像変更)
  - Animation(アニメーション)

OnClick(): クリック時のイベント

スクリプトでボタンイベント

using UnityEngine.UI;

public class ButtonExample : MonoBehaviour
{
    public Button myButton;

    void Start()
    {
        // リスナーを追加
        myButton.onClick.AddListener(OnButtonClick);
    }

    void OnButtonClick()
    {
        Debug.Log("Button clicked!");
    }
}

Inspectorから設定(推奨)

1. ButtonのInspector
2. OnClick() の「+」をクリック
3. 対象のGameObjectをドラッグ
4. 関数を選択(例: GameManager.StartGame)

Image(画像)

Imageの作成

Hierarchy > 右クリック > UI > Image

Imageの設定

  • Source Image: 表示する画像(Sprite)
  • Color: 色の乗算
  • Image Type: 表示タイプ

Image Typeの種類

  • Simple: そのまま表示
  • Sliced: 9スライスで伸縮(ボタン背景に最適)
  • Tiled: タイル状に繰り返し
  • Filled: 進行度表示(HPバーなど)

HPバーの実装

public class HealthBar : MonoBehaviour
{
    public Image healthBarFill;
    public float maxHealth = 100f;
    private float currentHealth;

    void Start()
    {
        currentHealth = maxHealth;
        UpdateHealthBar();
    }

    public void TakeDamage(float damage)
    {
        currentHealth -= damage;
        currentHealth = Mathf.Clamp(currentHealth, 0, maxHealth);
        UpdateHealthBar();
    }

    void UpdateHealthBar()
    {
        healthBarFill.fillAmount = currentHealth / maxHealth;
    }
}

Slider(スライダー)

Sliderの作成

Hierarchy > 右クリック > UI > Slider

Sliderの設定

Min Value: 最小値(例: 0)
Max Value: 最大値(例: 100)
Whole Numbers: 整数のみ
Value: 現在の値

OnValueChanged(): 値が変わった時のイベント

音量調整スライダー

using UnityEngine.UI;

public class VolumeControl : MonoBehaviour
{
    public Slider volumeSlider;

    void Start()
    {
        volumeSlider.onValueChanged.AddListener(OnVolumeChange);
        volumeSlider.value = AudioListener.volume;
    }

    void OnVolumeChange(float value)
    {
        AudioListener.volume = value;
    }
}

Panel(パネル)

Panelの作成

Hierarchy > 右クリック > UI > Panel

// 半透明の背景として使用

ポーズメニューの実装

public class PauseMenu : MonoBehaviour
{
    public GameObject pausePanel;
    private bool isPaused = false;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (isPaused)
                Resume();
            else
                Pause();
        }
    }

    void Pause()
    {
        pausePanel.SetActive(true);
        Time.timeScale = 0f; // ゲームを一時停止
        isPaused = true;
    }

    public void Resume()
    {
        pausePanel.SetActive(false);
        Time.timeScale = 1f;
        isPaused = false;
    }

    public void QuitGame()
    {
        Application.Quit();
    }
}

InputField(入力フィールド)

InputFieldの作成

Hierarchy > 右クリック > UI > Input Field - TextMeshPro

InputFieldの設定

Text: 初期テキスト
Character Limit: 最大文字数
Content Type: 入力タイプ
  - Standard(通常)
  - Integer Number(整数)
  - Decimal Number(小数)
  - Password(パスワード)
Placeholder: プレースホルダーテキスト

名前入力の実装

using TMPro;

public class NameInput : MonoBehaviour
{
    public TMP_InputField nameInput;
    public TextMeshProUGUI displayText;

    public void OnNameSubmit()
    {
        string playerName = nameInput.text;
        displayText.text = "Welcome, " + playerName + "!";
    }
}

レイアウトグループ

Horizontal Layout Group(横並び)

// 子要素を横に自動配置
Add Component > Layout > Horizontal Layout Group

Spacing: 要素間の間隔
Child Alignment: 配置位置
Child Force Expand: 自動拡張

Vertical Layout Group(縦並び)

// 子要素を縦に自動配置
Add Component > Layout > Vertical Layout Group

Grid Layout Group(グリッド)

// 格子状に配置
Add Component > Layout > Grid Layout Group

Cell Size: セルのサイズ
Spacing: 間隔
Constraint: 列数/行数の制約

インベントリUIの例

Canvas
└ Inventory Panel
  ├ Grid Layout Group(設定: Cell Size 100x100, Spacing 10)
  ├ Item Slot 1
  ├ Item Slot 2
  ├ Item Slot 3
  └ ...

実用的なUI例

例1: ゲームオーバー画面

public class GameOverUI : MonoBehaviour
{
    public GameObject gameOverPanel;
    public TextMeshProUGUI finalScoreText;

    void Start()
    {
        gameOverPanel.SetActive(false);
    }

    public void ShowGameOver(int score)
    {
        gameOverPanel.SetActive(true);
        finalScoreText.text = "Final Score: " + score;
        Time.timeScale = 0f;
    }

    public void RestartGame()
    {
        Time.timeScale = 1f;
        UnityEngine.SceneManagement.SceneManager.LoadScene(
            UnityEngine.SceneManagement.SceneManager.GetActiveScene().name
        );
    }
}

例2: フェードイン/アウト

using UnityEngine.UI;
using System.Collections;

public class FadeScreen : MonoBehaviour
{
    public Image fadeImage;

    void Start()
    {
        StartCoroutine(FadeIn());
    }

    IEnumerator FadeIn()
    {
        float alpha = 1f;
        while (alpha > 0)
        {
            alpha -= Time.deltaTime;
            fadeImage.color = new Color(0, 0, 0, alpha);
            yield return null;
        }
    }

    public IEnumerator FadeOut()
    {
        float alpha = 0f;
        while (alpha < 1)
        {
            alpha += Time.deltaTime;
            fadeImage.color = new Color(0, 0, 0, alpha);
            yield return null;
        }
    }
}

例3: タイマー表示

public class TimerUI : MonoBehaviour
{
    public TextMeshProUGUI timerText;
    private float timeRemaining = 60f;

    void Update()
    {
        if (timeRemaining > 0)
        {
            timeRemaining -= Time.deltaTime;
            UpdateTimerDisplay();
        }
        else
        {
            timeRemaining = 0;
            // ゲームオーバー処理
        }
    }

    void UpdateTimerDisplay()
    {
        int minutes = Mathf.FloorToInt(timeRemaining / 60);
        int seconds = Mathf.FloorToInt(timeRemaining % 60);
        timerText.text = string.Format("{0:00}:{1:00}", minutes, seconds);
    }
}

アニメーション

Animatorを使ったUIアニメーション

1. UIオブジェクトを選択
2. Window > Animation > Animation
3. Create New Animation
4. プロパティを記録(位置、スケール、透明度など)

スクリプトからアニメーション制御

public class MenuAnimator : MonoBehaviour
{
    private Animator animator;

    void Start()
    {
        animator = GetComponent();
    }

    public void ShowMenu()
    {
        animator.SetTrigger("Show");
    }

    public void HideMenu()
    {
        animator.SetTrigger("Hide");
    }
}

パフォーマンス最適化

1. Canvasの分割

  • すべてのUIを1つのCanvasに入れない
  • 静的UI(変わらない)と動的UI(変わる)を分ける

2. Raycast Targetの最適化

// クリック不要なImageはRaycast Targetをオフ
Image > Raycast Target: チェックを外す

3. 非表示時は無効化

// SetActive(false) でCanvasを無効化
panel.SetActive(false);

トラブルシューティング

UIが表示されない

  • CanvasのRender Modeを確認
  • Cameraが設定されているか(Camera mode時)
  • Canvasの順序(SortingOrder)を確認

ボタンが反応しない

  • EventSystemが存在するか確認
  • ButtonのInteractableがチェックされているか
  • 他のUIが上に重なっていないか

解像度で表示が崩れる

  • Canvas Scalerで「Scale With Screen Size」を使う
  • 適切なAnchorを設定

まとめ

Unity UIシステムをマスターすれば、プロフェッショナルなゲームUIが作れます

重要ポイント

  • CanvasがすべてのUIの土台
  • Rect TransformとAnchorで配置制御
  • TextMeshProで美しいテキスト
  • ButtonとEventでインタラクション
  • Layout Groupで自動配置

次のステップ

  • UI Toolkitの学習(新UI)
  • DOTweenでスムーズなアニメーション
  • カスタムシェーダーでエフェクト
  • スクロールビューの実装