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

如何将像素转换为世界空间单位,使精灵在全设备保持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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:30:44