返回 Skill 列表
extension
分类: 开发与工程无需 API Key

layout-sizing

当用户询问关于“布局”、“尺寸”、“坐标”、“1920x1080”、“世界单位”、“PPU”、“每单位像素数”、“SVG导入”、“纹理大小”、“网格定位”、“屏幕尺寸”、“摄像机”、“正交大小”、“保留区域”、“LayoutConfig”,或者讨论面板显示布局和精灵尺寸时,应使用此技能。

person作者: jakexiaohubgithub

Board Layout and Sizing

Expert knowledge of Board display layout, coordinate systems, SVG import settings, and sprite sizing for the 1920×1080 Board hardware.

Display Configuration

Target Display

| Metric | Pixels | World Units (100 PPU) | | ------ | ------ | --------------------- | | Width | 1920 | 19.2 | | Height | 1080 | 10.8 |

Camera Settings

| Setting | Value | | ----------------- | ----------- | | Orthographic Size | 5.4 | | Position | (0, 0, -10) | | Aspect Ratio | 16:9 |

Calculation: Visible Height = orthoSize × 2 = 10.8 world units

Horizontal Layout (19.2 world units)

|  Blue UI  | Blue Res | Buffer |   5×5 Grid   | Buffer | Red Res |  Red UI  |
|    2.1    |   2.0    |  0.5   |     10.0     |  0.5   |   2.0   |   2.1    |

Zone Coordinates

| Zone | Left | Right | Center | Width | | ----------------- | -------- | -------- | ------- | -------- | | Blue UI | -9.6 | -7.5 | -8.55 | 2.1 | | Blue Reserve | -7.5 | -5.5 | -6.5 | 2.0 | | Left Buffer | -5.5 | -5.0 | — | 0.5 | | Playable Grid | -5.0 | +5.0 | 0.0 | 10.0 | | Right Buffer | +5.0 | +5.5 | — | 0.5 | | Red Reserve | +5.5 | +7.5 | +6.5 | 2.0 | | Red UI | +7.5 | +9.6 | +8.55 | 2.1 |

Reserve Pool Purpose

  • Holds drawn tiles before placement (visible to both players)
  • Up to 3 tiles per player maximum
  • Tiles can be stolen from opponent's reserve

Vertical Layout (10.8 world units)

| Zone | Bottom | Top | Height | | ------------- | ------ | ---- | ------ | | Bottom Margin | -5.4 | -5.0 | 0.4 | | Playable Grid | -5.0 | +5.0 | 10.0 | | Top Margin | +5.0 | +5.4 | 0.4 |

LayoutConfig Reference

All layout constants centralized in Assets/Scripts/Config/LayoutConfig.cs:

public static class LayoutConfig
{
    // Screen dimensions
    public const float ScreenWidth = 19.2f;
    public const float ScreenHeight = 10.8f;

    // Tile and grid
    public const float TileSize = 2.0f;
    public const int GridSize = 5;

    // Grid boundaries
    public const float GridLeft = -5.0f;
    public const float GridRight = 5.0f;
    public const float GridBottom = -5.0f;
    public const float GridTop = 5.0f;

    // Camera
    public const float CameraOrthoSize = 5.4f;

    // Reserve zones
    public const float BlueReserveCenter = -6.5f;
    public const float RedReserveCenter = 6.5f;
}

Grid Positioning

Grid to World Conversion

// Grid (0,0) to (4,4) maps to world coordinates
float x = LayoutConfig.GridLeft + (gridX * LayoutConfig.TileSize) + (LayoutConfig.TileSize / 2f);
float y = LayoutConfig.GridBottom + (gridY * LayoutConfig.TileSize) + (LayoutConfig.TileSize / 2f);

Key Grid Positions

| Grid | World Center | Description | | ------ | ------------ | ---------------------- | | (0, 0) | (-4, -4) | Bottom-left | | (2, 2) | (0, 0) | Center (starting tile) | | (4, 4) | (4, 4) | Top-right | | (0, 4) | (-4, 4) | Top-left | | (4, 0) | (4, -4) | Bottom-right |

SVG Import Settings

THE GOLDEN RULE

╔═══════════════════════════════════════════════════════════════╗
║                                                               ║
║   WORLD SIZE = TEXTURE SIZE ÷ PIXELS PER UNIT                 ║
║                                                               ║
║   ALWAYS use PPU = 100. Adjust Texture Size for world size.   ║
║                                                               ║
╚═══════════════════════════════════════════════════════════════╝

Formula: Texture Size = Desired World Size × 100

Standard Settings

| Asset | Desired World Size | Texture Size | PPU | | ---------- | ------------------ | ------------ | --- | | Tiles | 2.0 | 200 | 100 | | Tokens | 0.4 (20% of tile) | 40 | 100 |

Import Steps

  1. Select SVG file(s) in Project window
  2. In Inspector:
    • Generated Asset Type: Texture2D
    • Texture Size: (calculated value)
    • Pixels Per Unit: 100
  3. Click Apply

Common Mistakes

| Mistake | Consequence | Solution | | -------------------------- | -------------------- | ------------------------------- | | Changing PPU | Inconsistent sizing | Always PPU = 100 | | Default Texture Size (256) | Wrong world size | Calculate: WorldSize × 100 | | Matching viewBox | Irrelevant to sizing | Set based on desired world size |

Rendering Order

Higher sorting order = renders in front.

| Layer | Sorting Order | Content | | ------------- | ------------- | --------------------------- | | Background | -10 | Solid color (#0D0F14) | | Tiles | 0 | TileView sprites | | Grid Glow | 1 | Wide semi-transparent lines | | Grid Core | 2 | Thin bright lines | | Reserve Lines | 1 | Zone boundaries | | Tokens | 10 | TokenView sprites |

Grid Visibility

Grid MUST have higher sorting order than tiles (1-2 vs 0) to appear above them.

Player Orientation

Players sit facing each other:

  • Blue player: Views from LEFT side (x < 0)
  • Red player: Views from RIGHT side (x > 0)

UI text rotation:

  • Blue UI: Normal rotation (readable from left)
  • Red UI: Rotated 180° (readable from right)

Edge Node Positions

Each tile has 4 edge nodes at side midpoints:

| Node | Offset from Tile Center | | ------ | ----------------------- | | Top | (0, +1.0) | | Right | (+1.0, 0) | | Bottom | (0, -1.0) | | Left | (-1.0, 0) |

Token Snapping

  • NodeSnapDistance = 0.5 world units (appropriate for TokenSize = 0.4)
  • Tokens snap to the nearest edge node within snap distance

EdgeNode and Tile Rotation

EdgeNode values (Top, Right, Bottom, Left) are tile-local coordinates that rotate with the tile:

// Rotate edge node by rotation steps (each step = 90 degrees clockwise)
public static EdgeNode RotateEdge(EdgeNode node, int rotationSteps)
{
    return (EdgeNode)(((int)node + rotationSteps) % 4);
}

// Example: A path from Left to Top on an unrotated tile
// After 1 rotation step (90 CW): becomes Bottom to Right

Center Tile Special Case:

  • Center tile (game-tile-13) is the ONLY tile that cannot rotate
  • Blue Attack starts on Left node, Red Attack starts on Right node
  • These starting positions are fixed and hardcoded per game rules

Coordinate System Summary

                    World Y
                       ↑
                       |  +5.4 (screen top)
                       |  +5.0 (grid top)
                       |
-9.6 ←─────────────────┼─────────────────→ +9.6  World X
                       |
                       |  -5.0 (grid bottom)
                       |  -5.4 (screen bottom)
                       ↓

Troubleshooting

Camera not showing full screen

Cause: Wrong orthographic size Solution: Set Camera → Orthographic Size = 5.4

Tiles too large/small

Cause: Wrong SVG Texture Size Solution: Texture Size = World Size × 100

  • Tiles: 200 (2.0 × 100)
  • Tokens: 40 (0.4 × 100)

Grid lines hidden behind tiles

Cause: Sorting order wrong Solution: Grid sorting order (1-2) must be higher than tiles (0)

Sprites not aligning

Cause: Not using LayoutConfig Solution: Always use LayoutConfig constants for positioning

Why 5×5 Grid?

  • Balanced gameplay: Enough space for strategy, small enough for quick games
  • Fits display: 10.0 world units fills the 1920×1080 display with room for UI
  • Network aesthetic: 5×5 creates interconnected network paths matching cybersecurity theme

Reference Files

This skill's references/ folder contains:

| File | Contains | Read When | | ------------------------ | --------------------------------------- | ---------------------------------- | | coordinate-systems.md | Grid, World, Screen conversion formulas | Implementing coordinate transforms | | layout-config.md | All LayoutConfig constants and values | Need exact constant values | | svg-import-settings.md | PPU=100 rule, Texture Size formula | Importing new SVG assets | | player-zones.md | Reserve pools, hand areas, stealing | Implementing reserve functionality |

Key Source Files

| File | Purpose | | --------------------------------------- | -------------------- | | Assets/Scripts/Config/LayoutConfig.cs | All layout constants |

Quick Reference

PPU = 100 (ALWAYS)
Texture Size = World Size × 100
NodeSnapDistance = 0.5 world units

Tiles:  2.0 world units → Texture Size = 200
Tokens: 0.4 world units → Texture Size = 40