如何将像素转换为世界空间单位,使精灵在全设备保持1.5英寸尺寸?
让Sprite在所有设备上保持1.5英寸显示尺寸的实现方案
需求说明
需要确保Sprite在任意设备上都显示为1.5英寸大小,已通过Screen.dpi * 1.5f计算出对应像素长度,接下来需要将该像素值转换为世界空间单位,以此正确缩放Sprite。
核心转换逻辑
世界空间单位与屏幕像素的对应关系取决于相机类型(正交/透视),以下分两种场景说明:
1. 正交相机场景
正交相机的orthographicSize代表视口垂直方向一半的世界单位长度,对应屏幕像素高度为Screen.height:
- 计算每像素对应的世界单位:
float worldUnitsPerPixel = (camera.orthographicSize * 2f) / Screen.height; - 像素长度转世界空间长度:
float worldLength = pixelLength * worldUnitsPerPixel;
2. 透视相机场景
透视相机需考虑物体到相机的距离(假设距离为zDistance):
- 计算视口垂直方向对应的世界长度:
float verticalWorldLength = 2f * zDistance * Mathf.Tan(camera.fieldOfView * Mathf.Deg2Rad / 2f); - 计算每像素对应的世界单位:
float worldUnitsPerPixel = verticalWorldLength / Screen.height; - 像素长度转世界空间长度:
float worldLength = pixelLength * worldUnitsPerPixel;
完整实现代码
using UnityEngine; public class SpriteFixedSize : MonoBehaviour { public Camera targetCamera; public float targetInchSize = 1.5f; private SpriteRenderer spriteRenderer; void Awake() { spriteRenderer = GetComponent<SpriteRenderer>(); if (targetCamera == null) targetCamera = Camera.main; } void Start() { AdjustSpriteSize(); } void AdjustSpriteSize() { // 处理DPI为0的 fallback 情况(部分设备可能无法获取有效DPI) float dpi = Screen.dpi > 0 ? Screen.dpi : 96f; float targetPixelLength = dpi * targetInchSize; float worldUnitsPerPixel; if (targetCamera.orthographic) { // 正交相机计算逻辑 worldUnitsPerPixel = (targetCamera.orthographicSize * 2f) / Screen.height; } else { // 透视相机计算逻辑,获取物体与相机的z轴距离 float zDistance = Mathf.Abs(transform.position.z - targetCamera.transform.position.z); float verticalFOVRad = targetCamera.fieldOfView * Mathf.Deg2Rad; worldUnitsPerPixel = (2f * zDistance * Mathf.Tan(verticalFOVRad / 2f)) / Screen.height; } // 计算目标世界空间尺寸 float targetWorldLength = targetPixelLength * worldUnitsPerPixel; // 获取Sprite原始像素尺寸 Vector2 originalPixelSize = spriteRenderer.sprite.rect.size; // 计算缩放比例,保持宽高比 float scaleRatio = targetWorldLength / originalPixelSize.x; // 应用缩放 transform.localScale = new Vector3(scaleRatio, scaleRatio, 1f); } }
注意事项
- 若设备无法返回有效
Screen.dpi,需设置默认DPI(代码中已加入96的 fallback 处理)。 - 若Sprite使用图集打包,需确保
sprite.rect.size能正确获取Sprite的实际像素尺寸,必要时可手动指定原始尺寸。 - 透视相机下,若物体与相机的距离发生变化,需重新调用
AdjustSpriteSize()方法更新缩放。
内容的提问来源于stack exchange,提问作者Newboy11
相关产品推荐
相关产品推荐

