You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Unity中在3D空间内显示图片并保持宽高比

嘿Akshay,我来帮你搞定Unity里Plane显示图片保持宽高比的问题!下面几个实用方法应该能解决你的挤压困扰:

解决Unity Plane图片挤压问题的方案

方法1:手动调整Plane尺寸(适合静态已知图片)

如果你提前知道图片的宽高比,可以直接手动调整Plane的缩放来匹配:

  • 先算出图片的宽高比:宽高比 = 图片宽度 / 图片高度(比如1920x1080的图片比例就是16/9≈1.777)
  • 选中Plane,在Inspector面板找到Transform组件的Scale属性
  • 注意:Plane默认的Mesh实际尺寸是10x10单位(X轴宽10,Y轴高10),所以我们只需要调整Scale的X或Y值来匹配比例:
    • 保持Y轴缩放为1,把X轴缩放设为你的图片宽高比(比如1.777),这样Plane的宽高比就和图片一致,纹理不会变形
    • 如果想固定Plane的宽度,比如让宽度保持10单位,那可以计算Y轴缩放为1 / 宽高比,同样能保持比例

方法2:代码动态调整(适合网络下载的动态图片)

如果图片是从网络下载的,没法提前知道比例,用代码自动调整是最优解。下面是一个完整的C#脚本示例:

using UnityEngine;
using UnityEngine.Networking;

public class DynamicImageHandler : MonoBehaviour
{
    public string targetImageUrl;
    private Renderer _planeRenderer;

    void Start()
    {
        _planeRenderer = GetComponent<Renderer>();
        StartCoroutine(DownloadAndAdjustImage());
    }

    IEnumerator DownloadAndAdjustImage()
    {
        using (UnityWebRequest webRequest = UnityWebRequestTexture.GetTexture(targetImageUrl))
        {
            yield return webRequest.SendWebRequest();

            if (webRequest.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError($"图片下载失败:{webRequest.error}");
                yield break;
            }

            // 获取下载的纹理
            Texture2D downloadedTexture = ((DownloadHandlerTexture)webRequest.downloadHandler).texture;
            _planeRenderer.material.mainTexture = downloadedTexture;

            // 计算图片宽高比并调整Plane缩放
            float imageAspectRatio = (float)downloadedTexture.width / downloadedTexture.height;
            // 保持Y轴缩放为1,X轴按比例适配
            transform.localScale = new Vector3(imageAspectRatio, 1f, 1f);

            // 如果你想固定Plane的总宽度(比如设为10单位),可以用下面的代码替换上面的缩放设置:
            // float fixedWidth = 10f;
            // float calculatedHeight = fixedWidth / imageAspectRatio;
            // transform.localScale = new Vector3(fixedWidth / 10f, calculatedHeight / 10f, 1f);
        }
    }
}
  • 把这个脚本挂在你的Plane对象上,填入目标图片的URL即可。运行后会自动下载图片,计算比例并调整Plane缩放,完全避免挤压。

方法3:调整材质UV坐标(固定Plane尺寸的场景)

如果需要保持Plane的大小不变,只想让图片在Plane内居中显示并保持比例(多余区域留空),可以通过调整材质的UV来实现:

  • 先给Plane替换一个Unlit/Texture材质(默认的Standard材质也可以,但Unlit更适合显示2D图片)
  • 挂载下面的脚本自动调整UV:
using UnityEngine;

public class UVAspectRatioFixer : MonoBehaviour
{
    private Renderer _planeRenderer;
    private Texture2D _currentTexture;

    void Start()
    {
        _planeRenderer = GetComponent<Renderer>();
        _currentTexture = _planeRenderer.material.mainTexture as Texture2D;
        AdjustUVToFit();
    }

    void AdjustUVToFit()
    {
        if (_currentTexture == null) return;

        // 计算Plane和图片的宽高比
        float planeAspect = transform.localScale.x / transform.localScale.y;
        float imageAspect = (float)_currentTexture.width / _currentTexture.height;

        Vector2 uvScale = Vector2.one;
        Vector2 uvOffset = Vector2.zero;

        if (planeAspect > imageAspect)
        {
            // Plane比图片宽,缩小图片的X轴缩放,左右留空
            uvScale.x = imageAspect / planeAspect;
            uvOffset.x = (1 - uvScale.x) / 2;
        }
        else
        {
            // Plane比图片高,缩小图片的Y轴缩放,上下留空
            uvScale.y = planeAspect / imageAspect;
            uvOffset.y = (1 - uvScale.y) / 2;
        }

        // 应用UV调整到材质
        _planeRenderer.material.mainTextureScale = uvScale;
        _planeRenderer.material.mainTextureOffset = uvOffset;
    }

    // 如果动态替换图片,调用这个方法更新UV
    public void UpdateDisplayedTexture(Texture2D newTexture)
    {
        _currentTexture = newTexture;
        _planeRenderer.material.mainTexture = newTexture;
        AdjustUVToFit();
    }
}
  • 这个方法下Plane的尺寸不会改变,图片会自动居中,多余的区域会显示材质的底色(你可以把材质的颜色设为透明或者和场景背景一致)。

内容的提问来源于stack exchange,提问作者Akshay Shah

火山引擎 最新活动