NaughtyAttributes ShowAssetPreview 详解:在 Unity Inspector 中直接预览 Sprite 与 Prefab 资源
游戏开发开发工具【免费下载链接】NaughtyAttributesAttribute Extensions for Unity项目地址https://gitcode.com/gh_mirrors/na/NaughtyAttributes点击查看免费下载ShowAssetPreview是 NaughtyAttributes 提供的一个 Drawer Attribute抽屉属性它能在 Unity Inspector 中直接渲染指定资源的纹理预览Texture Preview让 Sprite、Prefab、Material、Mesh 等UnityEngine.Object类型的字段无需点击即可所见即所得。本文以官方文档 show_asset_preview.rst 为主线结合仓库内属性定义、PropertyDrawer 实现与测试用例讲解它的声明方式、自定义尺寸参数、底层渲染原理与适用限制帮助你快速把它接入自己的编辑器工作流。一、ShowAssetPreview 是什么按官方文档的定位ShowAssetPreview 的作用是Shows the texture preview of a given asset (Sprite, Prefab...)即为某个资源类型的字段显示纹理预览。它属于 Drawer Attributes 家族同类还有 Dropdown、Scene、ProgressBar 等只负责如何绘制这一件事不改写字段的序列化值也不做数据校验。绘制逻辑统一由编辑器侧的 PropertyDrawer 承担运行时Build 后的 Player不会产生任何额外开销。在源码中该属性的完整声明位于 ShowAssetPreviewAttribute.cs[AttributeUsage(AttributeTargets.Field, AllowMultiple false, Inherited true)] public class ShowAssetPreviewAttribute : DrawerAttribute { public const int DefaultWidth 64; public const int DefaultHeight 64; public int Width { get; private set; } public int Height { get; private set; } public ShowAssetPreviewAttribute(int width DefaultWidth, int height DefaultHeight) { Width width; Height height; } }它继承自 DrawerAttribute.csDrawerAttribute : PropertyAttribute, INaughtyAttribute并受AttributeUsage约束AttributeTargets.Field只能标注在字段上AllowMultiple false同一字段最多只能挂一个Inherited true子类继承字段上的该属性。二、基本用法一行代码为字段加上预览官方文档给出的最小示例见 show_asset_preview.rst如下public class NaughtyComponent : MonoBehaviour { [ShowAssetPreview] public Sprite sprite; [ShowAssetPreview(128, 128)] public GameObject prefab; }第一个字段sprite使用了无参形式预览区按默认尺寸64 × 64预留第二个字段prefab使用了带参形式ShowAssetPreview(128, 128)将预览尺寸显式指定为 128 × 128。把这个组件挂到场景对象上Inspector 中字段下方就会多出一块资源预览区域如上图所示Sprite 直接显示其纹理内容GameObject/Prefab 则显示 Unity 生成的资产缩略图。这在排查美术资源、确认 Prefab 引用是否指错对象时非常直观。三、尺寸参数width 与 height 的默认值与语义构造函数签名是ShowAssetPreviewAttribute(int width DefaultWidth, int height DefaultHeight)两个参数都有默认值默认常量定义在属性类中参数默认值常量名说明width64DefaultWidth预览宽度保留参数见下方实现说明height64DefaultHeight预览高度决定 Inspector 为预览额外预留的行高因此以下两种写法完全等价[ShowAssetPreview] public Sprite a; [ShowAssetPreview(64, 64)] public Sprite b;从 ShowAssetPreviewPropertyDrawer.cs 的实现看GetReservedPreviewSize(property)通过PropertyUtility.GetAttributeShowAssetPreviewAttribute(property)反射读取字段上的属性实例拿不到时就回落到DefaultWidth/DefaultHeight常量private static Vector2 GetReservedPreviewSize(SerializedProperty property) { int targetWidth ShowAssetPreviewAttribute.DefaultWidth; int targetHeight ShowAssetPreviewAttribute.DefaultHeight; ShowAssetPreviewAttribute showAssetPreviewAttribute PropertyUtility.GetAttributeShowAssetPreviewAttribute(property); if (showAssetPreviewAttribute ! null) { targetWidth showAssetPreviewAttribute.Width; targetHeight showAssetPreviewAttribute.Height; } return new Vector2(targetWidth, targetHeight); }有一点需要留意基于当前源码实现预览矩形的高度取自Height参数用于额外预留的绘制行高而宽度则直接铺满属性行可用宽度rect.width。也就是说Height是真正影响布局的参数Width作为 API 保留参数参与尺寸计算但在当前绘制路径中并不直接限制预览区宽度。如果你的美术资源比例与预览区不一致预览会被拉伸显示。四、底层原理PropertyDrawer 是怎么把预览画出来的4.1 入口PropertyDrawerBase 的通用管线ShowAssetPreview 的编辑器绘制类继承自 PropertyDrawerBase.cs。OnGUI是一个sealed的通用管线在真正绘制字段前依次完成可见性检查PropertyUtility.IsVisible(property)配合ShowIf/HideIf等 Meta 属性决定是否绘制校验器执行遍历字段上的ValidatorAttribute并执行对应校验启用状态检查配合ReadOnly、EnableIf/DisableIf等用EditorGUI.DisabledScope包裹实际绘制值变更回调EditorGUI.EndChangeCheck()后触发OnValueChanged回调。这意味着[ShowAssetPreview]可以和其他 Meta 属性如[ShowIf]、[ReadOnly]、[Label]、[BoxGroup]自由组合预览区会跟随这些条件一起显示/隐藏/禁用行为与其他 Drawer Attribute 完全一致。4.2 核心绘制ShowAssetPreviewPropertyDrawer具体逻辑在 ShowAssetPreviewPropertyDrawer.cs它通过[CustomPropertyDrawer(typeof(ShowAssetPreviewAttribute))]注册到 Unity 的绘制管线。OnGUI_Internal的核心分支如下① 只处理对象引用类型if (property.propertyType SerializedPropertyType.ObjectReference)只有ObjectReference类型的字段才会走预览逻辑Sprite、Texture、GameObject、Material、Mesh、AudioClip 等UnityEngine.Object派生类型都属于此类。② 空引用时只画字段本身if (property.objectReferenceValue null) { return GetPropertyHeight(property); }字段未赋值时高度与普通字段一致不预留预览空间也不会报错。③ 有引用时字段行 预览区字段行占EditorGUIUtility.singleLineHeight标准单行高度预览区紧贴其下Rect previewRect new Rect() { x rect.x NaughtyEditorGUI.GetIndentLength(rect), y rect.y EditorGUIUtility.singleLineHeight, width rect.width, height GetReservedPreviewSize(property).y }; GUI.Label(previewRect, previewTexture);预览区通过GUI.Label(previewRect, previewTexture)把Texture2D直接绘制在 Inspector 中x方向通过NaughtyEditorGUI.GetIndentLength(rect)见 NaughtyEditorGUI.cs内部使用EditorGUI.IndentedRect计算缩进偏移对齐到缩进后的位置保证嵌套字段如折叠面板内也能正确对齐。④ 预览纹理的来源AssetPreview.GetAssetPreviewTexture2D previewTexture AssetPreview.GetAssetPreview(target);预览纹理由 Unity 编辑器 APIAssetPreview.GetAssetPreview(Object)提供。它是一个异步接口首次请求时可能尚未生成完毕此时返回null代码会进入加载中分支#if UNITY_6000_4_OR_NEWER else if (AssetPreview.IsLoadingAssetPreview(target.GetEntityId())) #else else if (AssetPreview.IsLoadingAssetPreview(target.GetInstanceID())) #endif { EditorWindow focused EditorWindow.focusedWindow; if (focused ! null) { focused.Repaint(); } }当预览仍在异步生成时drawer 会对当前聚焦的编辑器窗口发起Repaint()促使 Inspector 持续刷新直到GetAssetPreview返回可用的Texture2D。这里还体现了对 Unity 6000.4 新 API 的兼容新版本使用Object.GetEntityId()代替旧版GetInstanceID()通过UNITY_6000_4_OR_NEWER条件编译分支区分。⑤ 非对象引用字段警告提示string message property.name doesnt have an asset preview; DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);如果[ShowAssetPreview]被错误地标在了int、string等非ObjectReference字段上drawer 会画一个黄色的 HelpBox 警告xxx doesnt have an asset preview同时照常绘制默认字段避免 Inspector 布局崩溃。HelpBox 高度由PropertyDrawerBase.GetHelpBoxHeight()提供singleLineHeight * 2。4.3 高度预留逻辑GetPropertyHeight_Internal决定整块区域的高度if (property.propertyType SerializedPropertyType.ObjectReference) { if (property.objectReferenceValue null) { return GetPropertyHeight(property); } return GetPropertyHeight(property) GetReservedPreviewSize(property).y; } else { return GetPropertyHeight(property) GetHelpBoxHeight(); }即字段自身高度 预览区高度或警告框高度。这正是 Unity PropertyDrawer 的标准做法——先在GetPropertyHeight中如实申报总高度再在OnGUI中按同样比例分割绘制区域保证布局不重叠。五、适用场景与注意事项5.1 支持的类型从SerializedPropertyType.ObjectReference判断可以看出凡是能作为对象引用被序列化的UnityEngine.Object类型都支持典型包括Sprite、Texture2D/TextureGameObjectPrefab 引用Material、Mesh、AudioClip其他自定义UnityEngine.Object派生资源5.2 限制与边界只能修饰字段AttributeTargets.Field且一个字段只允许一个 drawer 属性AllowMultiple false文档 Drawer Attributes 索引 明确说明 A field, property or function can have only one drawer attribute非ObjectReference字段会显示警告而非报错属于防御性设计预览依赖 Unity 编辑器资产预览缓存AssetPreview首次进入 Inspector 可能有一帧左右的异步加载延迟属于正常现象该属性是纯编辑器功能不会增加运行时Player开销。5.3 嵌套字段中的表现仓库的测试用例 ShowAssetPreviewTest.cs 展示了它在嵌套可序列化类中的行为——两个嵌套层级ShowAssetPreviewNest1、ShowAssetPreviewNest2内部各放了一个 Sprite 与一个 GameObject 字段分别使用默认尺寸与96 × 96[System.Serializable] public class ShowAssetPreviewNest1 { [ShowAssetPreview] public Sprite sprite1; [ShowAssetPreview(96, 96)] public GameObject prefab1; public ShowAssetPreviewNest2 nest2; }配合PropertyDrawerBase对includeChildren: true的处理见 PropertyDrawerBase.cs嵌套字段同样能获得正确的高度申报与预览绘制不会出现布局错位。这也说明在复杂的数据结构里放心使用。5.4 Inspector 入口NaughtyAttributes 通过 NaughtyInspector.cs[CustomEditor(typeof(UnityEngine.Object), true)]接管 Inspector 绘制只要组件上存在任意带INaughtyAttribute的字段就会走自定义绘制管线[ShowAssetPreview]的字段随之被 PropertyDrawer 正确渲染组件上没有 Naughty 属性时则回落DrawDefaultInspector()。六、如何安装与使用前提ShowAssetPreview随 NaughtyAttributes 包一起分发。根据 installation.rst 与 package.jsonUnity 版本要求Unity2022.3 或更高版本当前仓库包版本2.1.6com.dbrizov.naughtyattributes。三种安装方式任选其一① OpenUPM CLIopenupm add com.dbrizov.naughtyattributes② manifest.json 添加 Git URL在项目Packages/manifest.json中添加com.dbrizov.naughtyattributes: https://github.com/dbrizov/NaughtyAttributes.git#upm③ Unity Asset Store直接从 Asset Store 下载 NaughtyAttributes 资源包导入。安装完成后在脚本顶部使用NaughtyAttributes命名空间即可调用[ShowAssetPreview]仓库还自带了 Demo 场景见 Samples/DemoScene与整套测试脚本见 Scripts/Test可作为验证与参考。七、结语ShowAssetPreview用极小的语法成本一个字段上的属性声明换来了 Inspector 中直接的资源可视化——它把资源引用是否正确从打开资源管理器比对 GUID变成了扫一眼预览图。理解它背后的AssetPreview异步加载、高度申报与条件编译兼容逻辑也有助于你在自定义 PropertyDrawer 时复用同样的模式。若要进一步阅读源码推荐按这条链路深入属性声明 → PropertyDrawer 实现 → 绘制管线基类 → 测试用例。赞分享游戏开发开发工具【免费下载链接】NaughtyAttributesAttribute Extensions for Unity项目地址https://gitcode.com/gh_mirrors/na/NaughtyAttributes点击查看免费下载相关推荐终极指南NaughtyAttributes的ShowAssetPreview功能10个创意应用场景终极指南NaughtyAttributes的ShowAssetPreview功能10个创意应用场景 NaughtyAttributes是Unity开发中一款强游戏开发开发工具Limonade社区与生态系统如何参与贡献并获得支持的完整指南Limonade社区与生态系统如何参与贡献并获得支持的完整指南 Limonade是一个轻量级的PHP微框架专为快速Web开发和原型设计而生。这款框架以其简洁GitHub Copilot for Azure 预览版在 VS Code 中直接用 azure 管理 Azure 云资源GitHub Copilot for Azure 预览版在 VS Code 中直接用 azure 管理 Azure 云资源 2024 年 11 月 15 日文档教程上一篇如何用QtScrcpy实现零延迟手机投屏从游戏直播到办公演示的完整方案下一篇G-Helper华硕笔记本性能控制终极指南 - 免费开源替代Armoury Crate创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考