Claude Code Plugins

Community-maintained marketplace

Feedback

unity-game-ugui-design

@majiayu000/claude-skill-registry
2
0

Game UI design using Unity's uGUI (Canvas/RectTransform/Anchors). Includes game UI elements like HUD, health bars, inventory, skill bars, mobile responsive design, and Safe Area support. Use when: game UI design, HUD creation, Canvas setup, mobile UI, Anchors configuration

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md


name: unity-game-ugui-design description: Game UI design using Unity's uGUI (Canvas/RectTransform/Anchors). Includes game UI elements like HUD, health bars, inventory, skill bars, mobile responsive design, and Safe Area support. Use when: game UI design, HUD creation, Canvas setup, mobile UI, Anchors configuration allowed-tools: - mcp__unity-mcp-server__find_ui_elements - mcp__unity-mcp-server__click_ui_element - mcp__unity-mcp-server__get_ui_element_state - mcp__unity-mcp-server__set_ui_element_value - mcp__unity-mcp-server__simulate_ui_input - mcp__unity-mcp-server__add_component - mcp__unity-mcp-server__modify_component - mcp__unity-mcp-server__set_component_field - mcp__unity-mcp-server__list_components - mcp__unity-mcp-server__get_component_types - mcp__unity-mcp-server__create_gameobject - mcp__unity-mcp-server__modify_gameobject - mcp__unity-mcp-server__find_gameobject - mcp__unity-mcp-server__get_hierarchy - mcp__unity-mcp-server__edit_structured - mcp__unity-mcp-server__create_class - mcp__unity-mcp-server__read - mcp__unity-mcp-server__get_symbols

Unity Game uGUI Design Skill

A skill for game UI design using Unity's uGUI (Unity GUI) system. Provides a comprehensive game UI design guide including implementation patterns for game UI elements like HUD, health bars, inventory, dialogs, mobile responsive design, and Safe Area support.

Quick Start

Basic Canvas Setup

// 1. Create Canvas
mcp__unity-mcp-server__create_gameobject({
  name: "Canvas"
})

// 2. Add Canvas component
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas",
  componentType: "Canvas",
  properties: {
    renderMode: 0  // ScreenSpaceOverlay
  }
})

// 3. Add CanvasScaler (responsive design)
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas",
  componentType: "CanvasScaler",
  properties: {
    uiScaleMode: 1,  // ScaleWithScreenSize
    referenceResolution: { x: 1080, y: 1920 },  // Reference resolution
    screenMatchMode: 0,  // MatchWidthOrHeight
    matchWidthOrHeight: 0  // 0=Portrait priority, 1=Landscape priority
  }
})

// 4. Add GraphicRaycaster (for interaction)
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas",
  componentType: "GraphicRaycaster"
})

Game UI Types

Game UI is classified into 4 types based on placement and representation.

1. Diegetic UI

UI that exists within the game world. Characters can also perceive it.

  • Examples: Enemy HP bar above head, car dashboard, in-game signboards
  • Canvas Setting: World Space
  • Features: High immersion, 3D space display
// World Space Canvas (enemy HP bar above head)
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Enemy/HealthCanvas",
  componentType: "Canvas",
  properties: { renderMode: 2 }  // WorldSpace
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Enemy/HealthCanvas",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 100, y: 20 }
})

2. Non-Diegetic UI

Overlay UI visible only to the player.

  • Examples: HUD, score display, minimap, skill bar
  • Canvas Setting: Screen Space - Overlay
  • Features: Always in front, screen-fixed
// HUD overlay Canvas
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas",
  componentType: "Canvas",
  properties: { renderMode: 0 }  // ScreenSpaceOverlay
})

3. Spatial UI

UI that exists in 3D space but is not part of the game world.

  • Examples: Destination marker, interact icon, quest marker
  • Canvas Setting: Screen Space - Camera or World Space
  • Features: Billboard (always faces camera)
// Billboard marker
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/QuestMarker/Canvas",
  componentType: "Canvas",
  properties: { renderMode: 2 }  // WorldSpace
})

// Add billboard script
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/QuestMarker/Canvas",
  componentType: "BillboardUI"
})

4. Meta UI

Full-screen effect UI.

  • Examples: Damage red flash, stamina depletion vignette, status effect overlay
  • Canvas Setting: Screen Space - Overlay (frontmost sorting order)
  • Features: Full screen, transparency animation
// Damage flash Canvas
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/EffectCanvas",
  componentType: "Canvas",
  properties: {
    renderMode: 0,
    sortingOrder: 100  // Frontmost
  }
})

// Flash Image (full screen)
mcp__unity-mcp-server__create_gameobject({
  name: "DamageFlash",
  parentPath: "/EffectCanvas"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/EffectCanvas/DamageFlash",
  componentType: "Image",
  properties: {
    color: { r: 1, g: 0, b: 0, a: 0 }  // Transparent red
  }
})

HUD Screen Layout

Game HUDs have industry-standard placement conventions.

Standard Layout Diagram

┌─────────────────────────────────────────────────────┐
│  [HP/MP Bar]              [Mini Map] [Settings]     │  ← Top
│  ★ Top-Left: HP/MP/Stamina    Top-Right: Minimap, Settings
│                                                     │
│                                                     │
│  [Quest]                               [Buff Icons] │  ← Upper-Middle
│  ★ Quest objectives        Buff/Debuff icons        │
│                                                     │
│                      [Center]                       │
│                   Crosshair/Interact                │
│                                                     │
│  [Chat]                              [Inventory]    │  ← Lower-Middle
│                                                     │
│                                                     │
│          [Skill Bar]    [Action Buttons]            │  ← Bottom
│          ★ Skills/Items   Action buttons            │
└─────────────────────────────────────────────────────┘

Placement Principles

Position Anchor UI Elements Reason
Top-Left (0,1) HP/MP/Stamina Critical info, minimal eye movement
Top-Right (1,1) Minimap, Settings Auxiliary info, non-intrusive
Bottom-Left (0,0) Chat, Logs Infrequently viewed info
Bottom-Right (1,0) Inventory, Buttons Easy right-hand access
Bottom-Center (0.5,0) Skill bar Two-hand access, high importance
Center (0.5,0.5) Crosshair, Interact Center of vision

uGUI Implementation Example

// HP Bar (top-left placement)
mcp__unity-mcp-server__create_gameobject({
  name: "HPBar",
  parentPath: "/HUDCanvas/SafeArea"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/HPBar",
  componentType: "RectTransform",
  fieldPath: "anchorMin",
  value: { x: 0, y: 1 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/HPBar",
  componentType: "RectTransform",
  fieldPath: "anchorMax",
  value: { x: 0, y: 1 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/HPBar",
  componentType: "RectTransform",
  fieldPath: "pivot",
  value: { x: 0, y: 1 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/HPBar",
  componentType: "RectTransform",
  fieldPath: "anchoredPosition",
  value: { x: 20, y: -20 }  // 20px margin from top-left
})

// Minimap (top-right placement)
mcp__unity-mcp-server__create_gameobject({
  name: "Minimap",
  parentPath: "/HUDCanvas/SafeArea"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/Minimap",
  componentType: "RectTransform",
  fieldPath: "anchorMin",
  value: { x: 1, y: 1 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/Minimap",
  componentType: "RectTransform",
  fieldPath: "anchorMax",
  value: { x: 1, y: 1 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/Minimap",
  componentType: "RectTransform",
  fieldPath: "pivot",
  value: { x: 1, y: 1 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/Minimap",
  componentType: "RectTransform",
  fieldPath: "anchoredPosition",
  value: { x: -20, y: -20 }  // 20px margin from top-right
})

// Skill Bar (bottom-center placement)
mcp__unity-mcp-server__create_gameobject({
  name: "SkillBar",
  parentPath: "/HUDCanvas/SafeArea"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar",
  componentType: "RectTransform",
  fieldPath: "anchorMin",
  value: { x: 0.5, y: 0 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar",
  componentType: "RectTransform",
  fieldPath: "anchorMax",
  value: { x: 0.5, y: 0 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar",
  componentType: "RectTransform",
  fieldPath: "pivot",
  value: { x: 0.5, y: 0 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar",
  componentType: "RectTransform",
  fieldPath: "anchoredPosition",
  value: { x: 0, y: 20 }  // 20px margin from bottom
})

Game UI Elements

1. Health Bar / Resource Bar

Implements delayed damage display (red gauge gradually decreases after taking damage).

Prefab Structure

HealthBar (RectTransform)
├── Background (Image) - Background
├── DelayedFill (Image) - Delayed gauge (red)
├── Fill (Image) - Current value gauge (green)
└── Text (TextMeshProUGUI) - "100/100"

MCP Implementation

// Create health bar
mcp__unity-mcp-server__create_gameobject({
  name: "HealthBar",
  parentPath: "/HUDCanvas/SafeArea"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/HealthBar",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 200, y: 24 }
})

// Background
mcp__unity-mcp-server__create_gameobject({
  name: "Background",
  parentPath: "/HUDCanvas/SafeArea/HealthBar"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/HealthBar/Background",
  componentType: "Image",
  properties: {
    color: { r: 0.1, g: 0.1, b: 0.1, a: 0.8 }
  }
})

// Delayed gauge (Filled Image)
mcp__unity-mcp-server__create_gameobject({
  name: "DelayedFill",
  parentPath: "/HUDCanvas/SafeArea/HealthBar"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/HealthBar/DelayedFill",
  componentType: "Image",
  properties: {
    color: { r: 0.8, g: 0.2, b: 0.2, a: 1 },
    type: 3,  // Filled
    fillMethod: 0,  // Horizontal
    fillAmount: 1.0
  }
})

// Current value gauge
mcp__unity-mcp-server__create_gameobject({
  name: "Fill",
  parentPath: "/HUDCanvas/SafeArea/HealthBar"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/HealthBar/Fill",
  componentType: "Image",
  properties: {
    color: { r: 0.2, g: 0.8, b: 0.2, a: 1 },
    type: 3,  // Filled
    fillMethod: 0,  // Horizontal
    fillAmount: 1.0
  }
})

// Text
mcp__unity-mcp-server__create_gameobject({
  name: "Text",
  parentPath: "/HUDCanvas/SafeArea/HealthBar"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/HealthBar/Text",
  componentType: "TextMeshProUGUI",
  properties: {
    text: "100/100",
    fontSize: 14,
    alignment: 514  // Center
  }
})

C# Controller

// HealthBarController.cs
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class HealthBarController : MonoBehaviour
{
    [SerializeField] private Image fillImage;
    [SerializeField] private Image delayedFillImage;
    [SerializeField] private TextMeshProUGUI text;

    [SerializeField] private float delayedFillSpeed = 0.5f;

    private float currentHealth = 100f;
    private float maxHealth = 100f;
    private float delayedHealth = 100f;

    public void SetHealth(float health, float max)
    {
        currentHealth = Mathf.Clamp(health, 0, max);
        maxHealth = max;

        float ratio = currentHealth / maxHealth;
        fillImage.fillAmount = ratio;
        text.text = $"{(int)currentHealth}/{(int)maxHealth}";

        // When taking damage, delayed gauge stays
        // On healing, update immediately
        if (delayedHealth < currentHealth)
        {
            delayedHealth = currentHealth;
            delayedFillImage.fillAmount = ratio;
        }
    }

    void Update()
    {
        // Gradually decrease delayed gauge
        if (delayedHealth > currentHealth)
        {
            delayedHealth = Mathf.MoveTowards(
                delayedHealth,
                currentHealth,
                maxHealth * delayedFillSpeed * Time.deltaTime
            );
            delayedFillImage.fillAmount = delayedHealth / maxHealth;
        }
    }
}

2. Skill Cooldown

Displays remaining time with darkened overlay + rotating mask during cooldown.

Prefab Structure

SkillSlot (RectTransform)
├── Icon (Image) - Skill icon
├── CooldownOverlay (Image) - Darkened overlay (Radial Fill)
├── CooldownText (TextMeshProUGUI) - Remaining seconds
└── KeyHint (TextMeshProUGUI) - "Q"

MCP Implementation

// Create skill slot
mcp__unity-mcp-server__create_gameobject({
  name: "SkillSlot",
  parentPath: "/HUDCanvas/SafeArea/SkillBar"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 64, y: 64 }
})

// Icon
mcp__unity-mcp-server__create_gameobject({
  name: "Icon",
  parentPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot/Icon",
  componentType: "Image"
})

// Cooldown overlay (Radial Fill)
mcp__unity-mcp-server__create_gameobject({
  name: "CooldownOverlay",
  parentPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot/CooldownOverlay",
  componentType: "Image",
  properties: {
    color: { r: 0, g: 0, b: 0, a: 0.7 },
    type: 3,  // Filled
    fillMethod: 4,  // Radial360
    fillOrigin: 2,  // Top
    fillClockwise: false,
    fillAmount: 0
  }
})

// Cooldown text
mcp__unity-mcp-server__create_gameobject({
  name: "CooldownText",
  parentPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot/CooldownText",
  componentType: "TextMeshProUGUI",
  properties: {
    text: "",
    fontSize: 20,
    alignment: 514,  // Center
    fontStyle: 1  // Bold
  }
})

// Key hint
mcp__unity-mcp-server__create_gameobject({
  name: "KeyHint",
  parentPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/SkillBar/SkillSlot/KeyHint",
  componentType: "TextMeshProUGUI",
  properties: {
    text: "Q",
    fontSize: 12,
    alignment: 257  // BottomLeft
  }
})

C# Controller

// SkillSlotController.cs
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class SkillSlotController : MonoBehaviour
{
    [SerializeField] private Image icon;
    [SerializeField] private Image cooldownOverlay;
    [SerializeField] private TextMeshProUGUI cooldownText;

    private float cooldownDuration;
    private float cooldownRemaining;

    public void SetIcon(Sprite sprite)
    {
        icon.sprite = sprite;
    }

    public void StartCooldown(float duration)
    {
        cooldownDuration = duration;
        cooldownRemaining = duration;
    }

    public bool IsOnCooldown => cooldownRemaining > 0;

    void Update()
    {
        if (cooldownRemaining > 0)
        {
            cooldownRemaining -= Time.deltaTime;

            float ratio = cooldownRemaining / cooldownDuration;
            cooldownOverlay.fillAmount = ratio;

            if (cooldownRemaining > 1)
                cooldownText.text = Mathf.CeilToInt(cooldownRemaining).ToString();
            else if (cooldownRemaining > 0)
                cooldownText.text = cooldownRemaining.ToString("F1");
            else
            {
                cooldownText.text = "";
                cooldownOverlay.fillAmount = 0;
            }
        }
    }
}

3. Inventory Grid

Rarity-based border colors, stack count display, drag & drop support.

Prefab Structure

InventoryGrid (RectTransform + GridLayoutGroup)
└── ItemSlot (multiple)
    ├── Background (Image) - Rarity border
    ├── Icon (Image) - Item icon
    ├── StackCount (TextMeshProUGUI) - "x99"
    └── SelectionHighlight (Image) - Selection highlight

MCP Implementation

// Create inventory grid
mcp__unity-mcp-server__create_gameobject({
  name: "InventoryGrid",
  parentPath: "/InventoryCanvas/Panel"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/InventoryCanvas/Panel/InventoryGrid",
  componentType: "GridLayoutGroup",
  properties: {
    cellSize: { x: 64, y: 64 },
    spacing: { x: 4, y: 4 },
    startCorner: 0,  // UpperLeft
    startAxis: 0,    // Horizontal
    childAlignment: 0,  // UpperLeft
    constraint: 1,  // FixedColumnCount
    constraintCount: 6  // 6 columns
  }
})

// Create item slot
mcp__unity-mcp-server__create_gameobject({
  name: "ItemSlot",
  parentPath: "/InventoryCanvas/Panel/InventoryGrid"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 64, y: 64 }
})

// Background (rarity border)
mcp__unity-mcp-server__create_gameobject({
  name: "Background",
  parentPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot/Background",
  componentType: "Image",
  properties: {
    color: { r: 0.3, g: 0.3, b: 0.3, a: 1 }  // Default (Common)
  }
})

// Icon
mcp__unity-mcp-server__create_gameobject({
  name: "Icon",
  parentPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot/Icon",
  componentType: "Image"
})

// Stack count
mcp__unity-mcp-server__create_gameobject({
  name: "StackCount",
  parentPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot/StackCount",
  componentType: "TextMeshProUGUI",
  properties: {
    text: "",
    fontSize: 12,
    alignment: 260  // BottomRight
  }
})

// Selection highlight
mcp__unity-mcp-server__create_gameobject({
  name: "SelectionHighlight",
  parentPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/InventoryCanvas/Panel/InventoryGrid/ItemSlot/SelectionHighlight",
  componentType: "Image",
  properties: {
    color: { r: 1, g: 1, b: 1, a: 0.3 },
    raycastTarget: false
  }
})

Rarity Color Definition

// ItemRarity.cs
using UnityEngine;

public enum ItemRarity
{
    Common,    // Gray
    Uncommon,  // Green
    Rare,      // Blue
    Epic,      // Purple
    Legendary  // Orange
}

public static class RarityColors
{
    public static Color GetColor(ItemRarity rarity) => rarity switch
    {
        ItemRarity.Common => new Color(0.6f, 0.6f, 0.6f),
        ItemRarity.Uncommon => new Color(0.2f, 0.8f, 0.2f),
        ItemRarity.Rare => new Color(0.2f, 0.4f, 0.9f),
        ItemRarity.Epic => new Color(0.6f, 0.2f, 0.9f),
        ItemRarity.Legendary => new Color(1.0f, 0.5f, 0.0f),
        _ => Color.white
    };
}

4. Damage Numbers (Floating Text)

Effect where numbers float up and fade from the damage location.

Prefab Structure

DamageNumber (RectTransform)
└── Text (TextMeshProUGUI) - Damage value

MCP Implementation

// Create damage number prefab
mcp__unity-mcp-server__create_gameobject({
  name: "DamageNumber",
  parentPath: "/WorldCanvas"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/WorldCanvas/DamageNumber",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 100, y: 40 }
})

// Text
mcp__unity-mcp-server__create_gameobject({
  name: "Text",
  parentPath: "/WorldCanvas/DamageNumber"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/WorldCanvas/DamageNumber/Text",
  componentType: "TextMeshProUGUI",
  properties: {
    text: "999",
    fontSize: 24,
    alignment: 514,  // Center
    fontStyle: 1,    // Bold
    color: { r: 1, g: 0.2, b: 0.2, a: 1 }
  }
})

C# Controller (with animation)

// DamageNumberController.cs
using UnityEngine;
using TMPro;

public class DamageNumberController : MonoBehaviour
{
    [SerializeField] private TextMeshProUGUI text;
    [SerializeField] private float floatSpeed = 50f;
    [SerializeField] private float fadeSpeed = 2f;
    [SerializeField] private float lifetime = 1.5f;

    private float elapsed;
    private Color originalColor;
    private Vector3 randomOffset;

    public void Setup(int damage, bool isCritical = false)
    {
        text.text = damage.ToString();

        if (isCritical)
        {
            text.fontSize *= 1.5f;
            text.color = new Color(1f, 0.8f, 0f);  // Yellow
        }

        originalColor = text.color;
        randomOffset = new Vector3(Random.Range(-20f, 20f), 0, 0);
    }

    void Update()
    {
        elapsed += Time.deltaTime;

        // Float upward
        transform.localPosition += (Vector3.up * floatSpeed + randomOffset) * Time.deltaTime;
        randomOffset *= 0.95f;  // Dampen horizontal movement

        // Fade out
        if (elapsed > lifetime * 0.5f)
        {
            float alpha = Mathf.Lerp(originalColor.a, 0,
                (elapsed - lifetime * 0.5f) / (lifetime * 0.5f));
            text.color = new Color(originalColor.r, originalColor.g, originalColor.b, alpha);
        }

        if (elapsed >= lifetime)
        {
            Destroy(gameObject);
        }
    }
}

5. Minimap

Top-down minimap using RawImage and RenderTexture.

Structure

MinimapContainer (RectTransform)
├── MapImage (RawImage + Mask) - Map display
├── PlayerIcon (Image) - Player icon
├── Border (Image) - Border
└── CompassText (TextMeshProUGUI) - "N"

MCP Implementation

// Minimap container
mcp__unity-mcp-server__create_gameobject({
  name: "MinimapContainer",
  parentPath: "/HUDCanvas/SafeArea"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/MinimapContainer",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 150, y: 150 }
})

// Map display (RawImage)
mcp__unity-mcp-server__create_gameobject({
  name: "MapImage",
  parentPath: "/HUDCanvas/SafeArea/MinimapContainer"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/MinimapContainer/MapImage",
  componentType: "RawImage"
})

// Circular mask
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/MinimapContainer/MapImage",
  componentType: "Mask",
  properties: {
    showMaskGraphic: false
  }
})

// Player icon (centered)
mcp__unity-mcp-server__create_gameobject({
  name: "PlayerIcon",
  parentPath: "/HUDCanvas/SafeArea/MinimapContainer"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/MinimapContainer/PlayerIcon",
  componentType: "Image"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/HUDCanvas/SafeArea/MinimapContainer/PlayerIcon",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 16, y: 16 }
})

// Border
mcp__unity-mcp-server__create_gameobject({
  name: "Border",
  parentPath: "/HUDCanvas/SafeArea/MinimapContainer"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/HUDCanvas/SafeArea/MinimapContainer/Border",
  componentType: "Image",
  properties: {
    raycastTarget: false
  }
})

6. Dialog System

RPG-style conversation window. Displays speaker name, text, and choices.

Prefab Structure

DialogPanel (RectTransform + CanvasGroup)
├── SpeakerName (TextMeshProUGUI)
├── Portrait (Image) - Speaker portrait
├── DialogText (TextMeshProUGUI) - Dialog text
├── ChoicesContainer (VerticalLayoutGroup)
│   └── ChoiceButton (Button + TextMeshProUGUI)
└── ContinueIndicator (Image) - Continue arrow

MCP Implementation

// Dialog panel
mcp__unity-mcp-server__create_gameobject({
  name: "DialogPanel",
  parentPath: "/DialogCanvas"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/DialogCanvas/DialogPanel",
  componentType: "Image",
  properties: {
    color: { r: 0, g: 0, b: 0, a: 0.85 }
  }
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/DialogCanvas/DialogPanel",
  componentType: "CanvasGroup"
})

// Bottom stretch placement
mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/DialogCanvas/DialogPanel",
  componentType: "RectTransform",
  fieldPath: "anchorMin",
  value: { x: 0, y: 0 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/DialogCanvas/DialogPanel",
  componentType: "RectTransform",
  fieldPath: "anchorMax",
  value: { x: 1, y: 0.3 }
})

// Speaker name
mcp__unity-mcp-server__create_gameobject({
  name: "SpeakerName",
  parentPath: "/DialogCanvas/DialogPanel"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/DialogCanvas/DialogPanel/SpeakerName",
  componentType: "TextMeshProUGUI",
  properties: {
    text: "Villager A",
    fontSize: 20,
    fontStyle: 1,  // Bold
    color: { r: 1, g: 0.9, b: 0.4, a: 1 }
  }
})

// Portrait
mcp__unity-mcp-server__create_gameobject({
  name: "Portrait",
  parentPath: "/DialogCanvas/DialogPanel"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/DialogCanvas/DialogPanel/Portrait",
  componentType: "Image"
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/DialogCanvas/DialogPanel/Portrait",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 100, y: 100 }
})

// Dialog text
mcp__unity-mcp-server__create_gameobject({
  name: "DialogText",
  parentPath: "/DialogCanvas/DialogPanel"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/DialogCanvas/DialogPanel/DialogText",
  componentType: "TextMeshProUGUI",
  properties: {
    text: "Hello, traveler.",
    fontSize: 18,
    alignment: 257  // TopLeft
  }
})

// Choices container
mcp__unity-mcp-server__create_gameobject({
  name: "ChoicesContainer",
  parentPath: "/DialogCanvas/DialogPanel"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/DialogCanvas/DialogPanel/ChoicesContainer",
  componentType: "VerticalLayoutGroup",
  properties: {
    spacing: 8,
    childAlignment: 4  // MiddleCenter
  }
})

// Continue indicator
mcp__unity-mcp-server__create_gameobject({
  name: "ContinueIndicator",
  parentPath: "/DialogCanvas/DialogPanel"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/DialogCanvas/DialogPanel/ContinueIndicator",
  componentType: "Image"
})

Typewriter Effect

// DialogController.cs
using System.Collections;
using UnityEngine;
using TMPro;

public class DialogController : MonoBehaviour
{
    [SerializeField] private TextMeshProUGUI dialogText;
    [SerializeField] private GameObject continueIndicator;
    [SerializeField] private float charactersPerSecond = 30f;

    private string fullText;
    private bool isTyping;
    private bool skipRequested;

    public void ShowDialog(string text)
    {
        fullText = text;
        StartCoroutine(TypeText());
    }

    IEnumerator TypeText()
    {
        isTyping = true;
        continueIndicator.SetActive(false);
        dialogText.text = "";

        foreach (char c in fullText)
        {
            if (skipRequested)
            {
                dialogText.text = fullText;
                break;
            }

            dialogText.text += c;
            yield return new WaitForSeconds(1f / charactersPerSecond);
        }

        isTyping = false;
        skipRequested = false;
        continueIndicator.SetActive(true);
    }

    public void OnClick()
    {
        if (isTyping)
            skipRequested = true;
        else
            // Proceed to next dialog
            OnDialogComplete();
    }

    void OnDialogComplete()
    {
        // Implementation: Show next line or finish
    }
}

Core Concepts

1. Canvas Render Mode

Mode Use Case Features
Screen Space - Overlay General UI Rendered in front, no camera needed
Screen Space - Camera UI with 3D effects Camera reference, depth sorting
World Space In-world UI VR/AR, in-game signboards

2. RectTransform

RectTransform is the component that controls UI element position and size.

// Key RectTransform properties
mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/Button",
  componentType: "RectTransform",
  fieldPath: "anchoredPosition",
  value: { x: 0, y: 100 }  // Position relative to anchor
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/Button",
  componentType: "RectTransform",
  fieldPath: "sizeDelta",
  value: { x: 200, y: 60 }  // Size
})

3. Anchors

Anchors are the core of responsive design. They specify relative position to parent element using normalized values from 0 to 1.

Anchor Preset Reference

Preset anchorMin anchorMax Use Case
Center (0.5, 0.5) (0.5, 0.5) Popup, Dialog
Top-Left (0, 1) (0, 1) Status display
Top-Right (1, 1) (1, 1) Settings button
Bottom-Left (0, 0) (0, 0) Chat input
Bottom-Right (1, 0) (1, 0) Action buttons
Top Stretch (0, 1) (1, 1) Header
Bottom Stretch (0, 0) (1, 0) Footer
Left Stretch (0, 0) (0, 1) Side menu
Full Stretch (0, 0) (1, 1) Background
// Full stretch example
mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/Background",
  componentType: "RectTransform",
  fieldPath: "anchorMin",
  value: { x: 0, y: 0 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/Background",
  componentType: "RectTransform",
  fieldPath: "anchorMax",
  value: { x: 1, y: 1 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/Background",
  componentType: "RectTransform",
  fieldPath: "offsetMin",
  value: { x: 0, y: 0 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/Background",
  componentType: "RectTransform",
  fieldPath: "offsetMax",
  value: { x: 0, y: 0 }
})

Mobile Responsive Design

Canvas Scaler Settings

The key to mobile responsive design is proper CanvasScaler configuration.

Portrait Priority

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas",
  componentType: "CanvasScaler",
  fieldPath: "uiScaleMode",
  value: 1  // ScaleWithScreenSize
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas",
  componentType: "CanvasScaler",
  fieldPath: "referenceResolution",
  value: { x: 1080, y: 1920 }  // 9:16 portrait reference
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas",
  componentType: "CanvasScaler",
  fieldPath: "matchWidthOrHeight",
  value: 0  // 0 = Match width (optimal for portrait)
})

Landscape Priority

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas",
  componentType: "CanvasScaler",
  fieldPath: "referenceResolution",
  value: { x: 1920, y: 1080 }  // 16:9 landscape reference
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas",
  componentType: "CanvasScaler",
  fieldPath: "matchWidthOrHeight",
  value: 1  // 1 = Match height (optimal for landscape)
})

Both Orientations (Dynamic Match)

For supporting both orientations, switch Match at runtime.

// OrientationHandler.cs
using UnityEngine;
using UnityEngine.UI;

public class OrientationHandler : MonoBehaviour
{
    private CanvasScaler canvasScaler;
    private ScreenOrientation lastOrientation;

    void Start()
    {
        canvasScaler = GetComponent<CanvasScaler>();
        UpdateMatch();
    }

    void Update()
    {
        if (Screen.orientation != lastOrientation)
        {
            UpdateMatch();
            lastOrientation = Screen.orientation;
        }
    }

    void UpdateMatch()
    {
        bool isPortrait = Screen.height > Screen.width;
        canvasScaler.matchWidthOrHeight = isPortrait ? 0f : 1f;
    }
}

Safe Area Support (Notch Support)

Safe Area support for devices with notches or punch-hole cameras.

// SafeAreaHandler.cs
using UnityEngine;

public class SafeAreaHandler : MonoBehaviour
{
    private RectTransform panelRectTransform;
    private Rect lastSafeArea;

    void Start()
    {
        panelRectTransform = GetComponent<RectTransform>();
        ApplySafeArea();
    }

    void Update()
    {
        if (Screen.safeArea != lastSafeArea)
        {
            ApplySafeArea();
        }
    }

    void ApplySafeArea()
    {
        Rect safeArea = Screen.safeArea;
        lastSafeArea = safeArea;

        // Convert to normalized coordinates
        Vector2 anchorMin = safeArea.position;
        Vector2 anchorMax = safeArea.position + safeArea.size;

        anchorMin.x /= Screen.width;
        anchorMin.y /= Screen.height;
        anchorMax.x /= Screen.width;
        anchorMax.y /= Screen.height;

        panelRectTransform.anchorMin = anchorMin;
        panelRectTransform.anchorMax = anchorMax;
    }
}
// Create Safe Area panel
mcp__unity-mcp-server__create_gameobject({
  name: "SafeAreaPanel",
  parentPath: "/Canvas"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/SafeAreaPanel",
  componentType: "RectTransform"
})

// Set to full stretch
mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/SafeAreaPanel",
  componentType: "RectTransform",
  fieldPath: "anchorMin",
  value: { x: 0, y: 0 }
})

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/SafeAreaPanel",
  componentType: "RectTransform",
  fieldPath: "anchorMax",
  value: { x: 1, y: 1 }
})

// Add SafeAreaHandler script
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/SafeAreaPanel",
  componentType: "SafeAreaHandler"
})

Layout Groups

Layout Group components for automatic layouts.

Horizontal Layout Group

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/ButtonContainer",
  componentType: "HorizontalLayoutGroup",
  properties: {
    spacing: 10,
    childAlignment: 4,  // MiddleCenter
    childControlWidth: true,
    childControlHeight: true,
    childForceExpandWidth: false,
    childForceExpandHeight: false
  }
})

Vertical Layout Group

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/MenuList",
  componentType: "VerticalLayoutGroup",
  properties: {
    spacing: 5,
    childAlignment: 1,  // UpperCenter
    padding: { left: 10, right: 10, top: 10, bottom: 10 }
  }
})

Grid Layout Group

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/ItemGrid",
  componentType: "GridLayoutGroup",
  properties: {
    cellSize: { x: 100, y: 100 },
    spacing: { x: 10, y: 10 },
    startCorner: 0,  // UpperLeft
    startAxis: 0,    // Horizontal
    childAlignment: 4,  // MiddleCenter
    constraint: 1,  // FixedColumnCount
    constraintCount: 4
  }
})

Content Size Fitter

Automatically adjusts parent to fit child elements.

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/AutoSizePanel",
  componentType: "ContentSizeFitter",
  properties: {
    horizontalFit: 2,  // PreferredSize
    verticalFit: 2     // PreferredSize
  }
})

Tool Selection Guide

Purpose Recommended Tool
Create Canvas create_gameobject + add_component
Add UI element create_gameobject + add_component
Set anchors set_component_field (RectTransform)
Configure Canvas Scaler set_component_field (CanvasScaler)
Add Layout Group add_component
Search UI elements find_ui_elements
Test UI click click_ui_element
Check UI state get_ui_element_state
Create script create_class

Common Workflows

1. Creating Mobile Portrait UI

// Step 1: Create Canvas
mcp__unity-mcp-server__create_gameobject({ name: "MobileCanvas" })
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/MobileCanvas",
  componentType: "Canvas",
  properties: { renderMode: 0 }
})
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/MobileCanvas",
  componentType: "CanvasScaler",
  properties: {
    uiScaleMode: 1,
    referenceResolution: { x: 1080, y: 1920 },
    matchWidthOrHeight: 0
  }
})
mcp__unity-mcp-server__add_component({
  gameObjectPath: "/MobileCanvas",
  componentType: "GraphicRaycaster"
})

// Step 2: Safe Area panel
mcp__unity-mcp-server__create_gameobject({
  name: "SafeArea",
  parentPath: "/MobileCanvas"
})

// Step 3: Header (top stretch)
mcp__unity-mcp-server__create_gameobject({
  name: "Header",
  parentPath: "/MobileCanvas/SafeArea"
})
// Set anchors to top stretch...

// Step 4: Content (center stretch)
mcp__unity-mcp-server__create_gameobject({
  name: "Content",
  parentPath: "/MobileCanvas/SafeArea"
})

// Step 5: Footer (bottom stretch)
mcp__unity-mcp-server__create_gameobject({
  name: "Footer",
  parentPath: "/MobileCanvas/SafeArea"
})

2. Creating a Scroll View

// Create ScrollView
mcp__unity-mcp-server__create_gameobject({
  name: "ScrollView",
  parentPath: "/Canvas"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/ScrollView",
  componentType: "ScrollRect"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/ScrollView",
  componentType: "Image"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/ScrollView",
  componentType: "Mask"
})

// Create Content
mcp__unity-mcp-server__create_gameobject({
  name: "Content",
  parentPath: "/Canvas/ScrollView"
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/ScrollView/Content",
  componentType: "VerticalLayoutGroup",
  properties: {
    childControlHeight: false,
    childForceExpandHeight: false
  }
})

mcp__unity-mcp-server__add_component({
  gameObjectPath: "/Canvas/ScrollView/Content",
  componentType: "ContentSizeFitter",
  properties: {
    verticalFit: 2  // PreferredSize
  }
})

Common Mistakes

1. Incorrect Anchor Configuration

NG: Fixed position UI placement

// UI goes off-screen when screen size changes
anchoredPosition: { x: 500, y: 800 }

OK: Relative placement using anchors

// Fixed to parent's bottom-right
anchorMin: { x: 1, y: 0 }
anchorMax: { x: 1, y: 0 }
anchoredPosition: { x: -50, y: 50 }  // Margin

2. Missing Canvas Scaler Configuration

NG: Left as Constant Pixel Size

uiScaleMode: 0  // UI size becomes inappropriate when resolution changes

OK: Scale With Screen Size

uiScaleMode: 1
referenceResolution: { x: 1080, y: 1920 }
matchWidthOrHeight: 0  // or 1

3. No Safe Area Support

NG: Placing important UI directly under Canvas

  • UI gets hidden by notch
  • Overlaps with home indicator area

OK: Place within Safe Area panel

  • Dynamic adjustment with SafeAreaHandler script
  • Place important UI within Safe Area

4. Excessive Use of Layout Groups

NG: Applying Layout Groups to all UI

  • Performance degradation
  • Unintended layout changes

OK: Use only for dynamically changing lists

  • Manual placement for static UI
  • Use for scroll view content

5. Insufficient Aspect Ratio Consideration

NG: Assuming only 16:9

referenceResolution: { x: 1920, y: 1080 }
// Breaks on 9:16, 18:9, 21:9, etc.

OK: Consider multiple aspect ratios

  • Test with major aspect ratios
  • Anchor settings that don't break on extreme ratios
  • Use Aspect Ratio Fitter when needed

Tool Reference

find_ui_elements

mcp__unity-mcp-server__find_ui_elements({
  elementType: "Button",      // UI component type
  tagFilter: "MainMenu",      // GameObject tag
  namePattern: "Btn_*",       // Name pattern
  includeInactive: false,     // Include inactive
  canvasFilter: "MainCanvas"  // Parent Canvas name
})

click_ui_element

mcp__unity-mcp-server__click_ui_element({
  elementPath: "/Canvas/Button",
  clickType: "left",     // left, right, middle
  holdDuration: 0,       // ms
  position: { x: 0.5, y: 0.5 }  // 0-1 normalized
})

get_ui_element_state

mcp__unity-mcp-server__get_ui_element_state({
  elementPath: "/Canvas/Button",
  includeChildren: false,
  includeInteractableInfo: true
})

set_ui_element_value

mcp__unity-mcp-server__set_ui_element_value({
  elementPath: "/Canvas/InputField",
  value: "Hello World",
  triggerEvents: true
})

set_component_field (RectTransform)

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas/Panel",
  componentType: "RectTransform",
  fieldPath: "anchorMin",  // anchorMin, anchorMax, pivot, anchoredPosition, sizeDelta, offsetMin, offsetMax
  value: { x: 0, y: 0 }
})

set_component_field (CanvasScaler)

mcp__unity-mcp-server__set_component_field({
  gameObjectPath: "/Canvas",
  componentType: "CanvasScaler",
  fieldPath: "matchWidthOrHeight",  // uiScaleMode, referenceResolution, screenMatchMode, matchWidthOrHeight
  value: 0.5
})