unity AssetPreview详解

AssetPreview 是 Unity 编辑器(UnityEditor 命名空间)中的一个实用类,专门用于获取资源在 Project 窗口中显示的预览图。理解它的异步加载机制和缓存控制是编写高效编辑器工具的关键。

核心定位

与加载原始资源数据不同,AssetPreview 提供的是一种轻量级的视觉预览。它返回的是 Texture2D,可以直接用于 GUI.DrawTexture 或作为 GUIContent 的图标,非常适合构建自定义的资源管理窗口。

所有静态方法详解

以下是该类提供的全部静态方法,掌握它们可以帮你实现对预览加载流程的精细控制。

方法描述
‌GetAssetPreview‌ 这是最核心的方法。传入一个资源对象,‌异步‌返回该资源的预览 Texture2D。注意,由于是异步加载,首次调用可能会返回 null;你需要稍后再次请求,直到它返回有效纹理。也接受 int InstanceID的重载形式。
‌GetMiniThumbnail‌ 返回一个对象的小缩略图,类似于 Project 窗口中列表视图下显示的图标。通常用于制作紧凑的资源列表,加载过程同样是异步的。
‌GetMiniTypeThumbnail‌ 返回一个‌类型‌的缩略图,并非具体实例。例如,传入 typeof(Material),它会返回代表材质类型的小图标。这个功能在按类型分类资源时非常方便。
‌IsLoadingAssetPreview‌ 传入一个具体的资源对象,检查‌该资源‌的预览是否正在加载中。当返回 true 时,你可以让界面等待并稍后重绘。
‌IsLoadingAssetPreviews‌ 不带参数,检查‌任何请求过的‌预览是否仍在加载中。这非常适合用来判断是否能一次性开始渲染所有预览,或在全部加载完成后执行刷新操作。
‌SetPreviewTextureCacheSize‌ 设置预览纹理缓存的大小。合理的缓存大小可以避免重复加载,优化内存占用和渲染性能。该大小应设置为一个能够一次性容纳屏幕上所有可见预览图的数值。

实战:在 EditorWindow 中的正确处理流程

由于预览加载是异步的,你不能想当然地在 OnGUI 里直接拿到结果。正确的处理模式是结合 IsLoadingAssetPreview 方法进行“轮询式”渲染。

‌代码示例:构建一个简单的目标资源预览窗口‌

using UnityEngine;
using UnityEditor;

public class AssetPreviewerWindow : EditorWindow
{
    // 假设你需要预览的目标资源
    private Object targetAsset;
    private Texture2D previewTexture;

    [MenuItem("Tools/Asset Previewer")]
    static void Init()
    {
        AssetPreviewerWindow window = (AssetPreviewerWindow)GetWindow(typeof(AssetPreviewerWindow));
        window.Show();
    }

    private void OnGUI()
    {
        EditorGUILayout.HelpBox("将资源拖拽到下方槽位,即可看到预览图", MessageType.Info);
        targetAsset = EditorGUILayout.ObjectField("目标资源", targetAsset, typeof(Object), false);

        if (targetAsset == null)
        {
            previewTexture = null;
            return;
        }

        // 核心逻辑:检查特定资源是否仍在加载预览
        if (!AssetPreview.IsLoadingAssetPreview(targetAsset.GetInstanceID()))
        {
            // 预览已完成或未开始加载,现在可以安全地请求并获取
            previewTexture = AssetPreview.GetAssetPreview(targetAsset);

            if (previewTexture != null)
            {
                // 成功获取到预览,绘制在界面上
                float size = position.width;
                Rect rect = new Rect(0, 40, size, size);
                GUI.DrawTexture(rect, previewTexture, ScaleMode.ScaleToFit);
            }
            else
            {
                // 预览纹理为null,可能尚未开始加载
                EditorGUILayout.LabelField("正在请求预览...");
            }
        }
        else
        {
            // 预览仍在异步加载中,显示等待提示
            EditorGUILayout.LabelField("预览加载中...");
            Repaint(); // 关键:请求持续重绘,直到加载完成
        }
    }
}

进阶:预览缓存控制

对于一个复杂的编辑器窗口,可能会同时展示大量资源。为了性能,你应该提前设置好缓存。

// 在窗口初始化或首次 OnGUI 时进行设置
if (Event.current.type == EventType.Repaint)
{
    // 例如,设置缓存大小为100,防止在快速滚动时预览被反复清理和重新加载
    AssetPreview.SetPreviewTextureCacheSize(100);
}

局限性及专业替代方案

虽然 AssetPreview 很方便,但它有几点限制:

  1. ‌尺寸和样式不可控‌:预览图的尺寸由编辑器主题决定,你无法直接要求生成一张特定大小(比如 512x512)的纹理。
  2. ‌混合型结果‌:GetAssetPreview 对于不同类型的对象可能返回不同背景的图(如预制体有全透明背景,而模型文件则可能含有棋盘格背景),不太适合作为最终产物。
  3. ‌异步不确定性‌:复杂的逻辑依赖其回调机制会比较繁琐。

如果你需要生成风格统一、高质量、自定义背景且大小完全可控的预览图(例如为商店资源页制作预览),AssetPreview 就不够用了。此时,应转而使用 ‌PreviewRenderUtility‌。这套 API 允许你创建独立的“摄影棚”场景,完全控制灯光、相机位置和渲染目标,从而生成高度定制化的结果。  

posted on 2026-05-18 15:14  -冷夜-  阅读(31)  评论(0)    收藏  举报

导航