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 很方便,但它有几点限制:
- 尺寸和样式不可控:预览图的尺寸由编辑器主题决定,你无法直接要求生成一张特定大小(比如 512x512)的纹理。
- 混合型结果:
GetAssetPreview对于不同类型的对象可能返回不同背景的图(如预制体有全透明背景,而模型文件则可能含有棋盘格背景),不太适合作为最终产物。 - 异步不确定性:复杂的逻辑依赖其回调机制会比较繁琐。
如果你需要生成风格统一、高质量、自定义背景且大小完全可控的预览图(例如为商店资源页制作预览),AssetPreview 就不够用了。此时,应转而使用 PreviewRenderUtility。这套 API 允许你创建独立的“摄影棚”场景,完全控制灯光、相机位置和渲染目标,从而生成高度定制化的结果。
浙公网安备 33010602011771号