跳到主要内容

Unity 2D Camera Orthographic Size 与像素对应关系的常见误区

· 阅读需 3 分钟
Hanmi255
游戏开发 & AI研究者

Unity 2D Camera Orthographic Size 与像素对应关系的常见误区

问题描述

在开发2D餐厅管理游戏时,我遇到了一个令人困惑的问题:

  • Grid Cell Size: 0.32 × 0.32 units
  • Grid区域: 60 × 10 cells
  • 期望占据屏幕: 1920 × 300 pixels
  • 实际效果: Grid区域被严重压缩,无法占满窗口

问题截图示例

错误的理解

我最初的想法是:

Grid宽度 = 60 cells × 0.32 = 19.2 units
Grid高度 = 10 cells × 0.32 = 3.2 units
窗口大小 = 1920 × 300 pixels

理论上应该刚好占满窗口?

这是错误的! Unity的世界单位(units)和屏幕像素(pixels)之间并不是1:1对应的。

核心知识点

1. Orthographic Size 的真正含义

在Unity 2D中,Camera的Orthographic Size定义的是:

摄像机视口高度的一半(以世界单位计)

例如,如果Orthographic Size = 5:

  • 摄像机能看到的世界高度 = 5 × 2 = 10 units
  • 摄像机能看到的世界宽度 = 10 × (屏幕宽度/屏幕高度) units

2. 世界单位到像素的转换

转换公式:

像素/单位 = 屏幕高度(pixels) / (Orthographic Size × 2)

示例计算:

  • 屏幕高度 = 1080 pixels
  • Orthographic Size = 5
  • 像素/单位 = 1080 / (5 × 2) = 108 pixels/unit

这意味着世界中的1个unit在屏幕上显示为108像素。

3. 实际案例分析

正确的计算方法

要让特定尺寸的世界区域占满屏幕,需要反向计算:

步骤1: 确定目标

  • 世界区域高度: 3.2 units (10 cells × 0.32)
  • 窗口高度: 300 pixels
  • 目标: 让3.2 units占满300 pixels的高度

步骤2: 计算Orthographic Size

Orthographic Size = 世界区域高度 / 2
= 3.2 / 2
= 1.6

步骤3: 验证宽度

Camera可见宽度 = Orthographic Size × 2 × (窗口宽度/窗口高度)
= 1.6 × 2 × (1920/300)
= 1.6 × 2 × 6.4
= 20.48 units

Grid宽度 = 60 × 0.32 = 19.2 units ✓

19.2 < 20.48,可以完整显示!

步骤4: 验证像素密度

像素/单位 = 300 / (1.6 × 2) = 93.75 pixels/unit

Grid在屏幕上的实际尺寸:
- 宽度: 19.2 × 93.75 = 1800 pixels
- 高度: 3.2 × 93.75 = 300 pixels ✓

解决方案

  1. 直接设置Camera的Orthographic Size = 1.6

通用公式总结

已知世界尺寸,求Camera设置

// 让特定高度的世界区域占满屏幕
orthographicSize = worldHeight / 2f;

// 验证宽度是否足够
float visibleWidth = orthographicSize * 2f * (Screen.width / Screen.height);

已知Camera设置,求可见范围

// 可见的世界高度
float visibleHeight = orthographicSize * 2f;

// 可见的世界宽度
float visibleWidth = visibleHeight * (Screen.width / Screen.height);

// 像素密度
float pixelsPerUnit = Screen.height / visibleHeight;

经验教训

  1. 不要假设世界单位和像素是1:1对应的 - 它们的关系由Camera的Orthographic Size决定
  2. Orthographic Size是高度的一半 - 这是最容易忽略的细节
  3. 宽高比很重要 - 宽度的可见范围取决于屏幕的宽高比
  4. 动态缩放要小心 - 自适应脚本可能在特殊分辨率下产生意外效果

调试技巧

在Scene视图中:

  1. 选中Camera对象
  2. 观察绿色的Camera Gizmo边框
  3. 这个边框显示的就是Camera实际能看到的世界范围
  4. 对比你的Grid区域是否在边框内

在代码中添加调试信息:

Debug.Log($"Orthographic Size: {_camera.orthographicSize}");
Debug.Log($"Visible Height: {_camera.orthographicSize * 2f}");
Debug.Log($"Visible Width: {_camera.orthographicSize * 2f * _camera.aspect}");
Debug.Log($"Pixels Per Unit: {Screen.height / (_camera.orthographicSize * 2f)}");

参考资料