You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何将俯视截图的像素选区转换为世界单位区域?

解决正交相机截图选区到Unity世界坐标的转换问题

核心逻辑梳理

你使用的是正交相机,且orthographicSize等于相机Y轴高度,因此相机视口在垂直方向(对应截图高度)覆盖的世界范围是2 * orthographicSize(从Z=-orthographicSize到Z=+orthographicSize,对应截图的上下边缘)。基于这个范围和截图像素尺寸,可算出像素与世界单位的转换比例,再修正坐标系方向差异即可解决偏差问题。

正确转换代码实现

1. 定义输入参数

以你提供的示例值为例:

// 地图图像尺寸
float imgWidth = 500f;
float imgHeight = 500f;

// 选区像素参数:top(距图像顶部)、left(距图像左侧)、width、height
float selTop = 157f;
float selLeft = 342f;
float selWidth = 98f;
float selHeight = 25f;

// 相机高度(等于orthographicSize)
float cameraHeight = 5f;

2. 计算像素转世界单位的缩放比例

正交相机垂直方向的世界范围是2 * cameraHeight,对应截图的像素高度,因此比例为:

float pixelToWorldScale = (2 * cameraHeight) / imgHeight;

注:因为正交相机的宽高比与截图一致,X轴和Z轴的缩放比例完全相同,无需单独计算。

3. 转换选区的位置和尺寸

需要修正图像坐标系与Unity世界坐标系的方向差异(图像top向下递增,Unity Z轴向上递增):

// 计算选区左上角相对于图像中心的像素偏移
float pixelOffsetX = selLeft - imgWidth / 2f;
float pixelOffsetZ = (imgHeight / 2f) - selTop; // 反转Y轴方向,匹配Unity Z轴逻辑

// 转换为世界坐标偏移
float worldOffsetX = pixelOffsetX * pixelToWorldScale;
float worldOffsetZ = pixelOffsetZ * pixelToWorldScale;

// 选区的世界尺寸
float worldSelWidth = selWidth * pixelToWorldScale;
float worldSelHeight = selHeight * pixelToWorldScale;

4. 正确放置立方体

Unity中立方体的position是其中心坐标,因此需要将选区左上角坐标加上半宽半高:

GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
// 立方体中心坐标 = 选区左上角世界坐标 + 半宽/半高
cube.transform.position = new Vector3(
    worldOffsetX + worldSelWidth / 2f,
    0.1f,
    worldOffsetZ + worldSelHeight / 2f
);
cube.transform.localScale = new Vector3(worldSelWidth, 0.1f, worldSelHeight);

原代码的问题分析

你之前的代码存在三个核心错误:

  • 缩放逻辑错误:未使用正交相机的完整垂直范围(2*cameraHeight)计算像素比例,而是采用了top/2与distance_from_map的错误比值
  • 坐标系方向未修正:没有处理图像top向下递增与Unity Z轴向上递增的方向差异
  • 位置计算缺失中心偏移:直接用选区左上角坐标设置立方体位置,但立方体position对应中心,导致位置偏差

内容的提问来源于stack exchange,提问作者Gaël Koch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:39:50