
简介这份Unity资源包面向需要在项目中实现模型转PNG图片并导出的开发者尤其适合做商品展示、角色预览、UI缩略图或编辑器工具扩展的中高级用户。资源围绕三种实现方案展开其中最优方案支持任意控制相机方向与输出尺寸可让生成图片呈现期望的观察视角解决固定视角截图难以满足多样化需求的问题。压缩包共约2000个文件整体408.77MB包含大量bin、meta、dll等工程与依赖文件以及png、jpg、mat、fbx等贴图、材质与模型素材另有md说明、json配置、asset资源与cs脚本等结构完整便于直接导入Unity工程运行与二次修改。目前已有438人学习下载。读者可据此掌握从模型渲染到图片导出的完整思路理解不同方案的适用边界并借助现成工程快速验证视角控制与分辨率设置减少自行摸索成本。1. 从一次模型预览翻车说起Unity 里把模型变成 PNG 到底难在哪做 Unity 工具链的同行大概率都遇到过这种需求策划在 Excel 里维护了几百个道具想批量生成图标或者美术做完一批模型需要统一出一套缩略图给运营做图鉴。第一反应通常是截屏但截屏分辨率不可控、背景带场景、批量跑起来还依赖窗口焦点一旦切到后台就全黑。于是问题变成怎么在 Unity 里把任意模型渲染成一张干净的 PNG而且方向、大小、背景都能自己定。这个资源就是冲着这件事来的。它提供三种方案前两种是常见的 Camera 加 RenderTexture 思路最后一种能任意控制方向和大小让图片呈现你想要的视角。配套的工程里能看到 RuntimePreviewGenerator 的运行时程序集定义以及 ProjectSettings、QualitySettings、GraphicsSettings 这些渲染相关配置说明作者是把预览生成当成一个可复用的运行时模块在做而不是临时写个编辑器脚本。适合谁做编辑器扩展的工具向 TA、需要批量出图的美术管线开发、以及想在运行时给玩家展示模型缩略图的客户端。下面我按「先跑通、再调参、最后避坑」的顺序拆一遍。2. 三种方案横向拆解Camera、RenderTexture 与运行时预览生成器2.1 方案一直接截屏为什么最先被淘汰最朴素的做法是ScreenCapture.CaptureScreenshot把当前 Game 视图存成文件。它上手快但有几个硬伤分辨率跟着 Game 视图走改不了截的是整个屏幕模型周围全是场景必须等这一帧渲染完批量循环里时序很难控。我早期做道具图标时就栽在这跑一百个模型结果一半是上一帧的残留。所以这个方案只适合临时验证不适合进管线。2.2 方案二Camera RenderTexture可控但视角受限真正能进管线的是手动渲染。核心思路是新建一个临时 Camera把它对准模型渲染到一张 RenderTexture再读回像素写成 PNG。关键参数有三个RenderTexture的宽高决定出图分辨率Camera.fieldOfView或正交尺寸决定取景范围Camera.clearFlags加backgroundColor决定背景是纯色还是透明。这个方案已经能满足大部分图标需求但视角调整要靠手动摆 Camera 的 transform想批量出「正面、侧面、45 度」三视图就得反复算旋转容易出错。2.3 方案三RuntimePreviewGenerator任意方向和大小的关键资源里重点推的是 RuntimePreviewGenerator 这套运行时方案。它把「摆相机、算包围盒、渲染、读像素」封装成一个调用你只需要传模型、旋转角度、图片尺寸和背景色。它能任意控制方向和大小的原因在于内部会根据模型的包围盒自动计算相机距离和正交范围保证模型始终填满画面且不被裁切同时允许你直接传一个欧拉角来指定观察方向。这就把「视角」从手动摆相机变成了传参批量出图时只要遍历角度列表即可。2.4 三种方案怎么选方案分辨率可控背景可控视角可控批量友好适用场景截屏否否否差临时验证Camera RenderTexture是是手动中固定视角图标RuntimePreviewGenerator是是传参好批量多视角出图选型逻辑很直接只要涉及批量或者多视角直接上第三种前两种了解原理即可避免重复造轮子。3. 动手跑通 RuntimePreviewGenerator从程序集配置到出图3.1 先确认程序集和渲染配置到位资源里带了RuntimePreviewGenerator.Runtime.asmdef这是运行时程序集定义。如果你的项目用了 Assembly Definition 来管理编译必须确保预览生成器所在的程序集被正确引用否则会出现「编辑器里能跑、打包后找不到类型」的玄学问题。同时GraphicsSettings.asset和QualitySettings.asset决定了默认渲染管线和抗锯齿等级出图有锯齿或者颜色发灰先回来查这两个文件。3.2 核心调用一行生成一张 PNG下面是我常用的封装把模型实例化到临时位置、生成贴图、写文件、清理现场串起来。using UnityEngine; using System.IO; public static class ModelThumbnail { // modelPrefab: 要出图的模型预制体 // angle: 观察方向例如 new Vector3(0, 45, 0) 表示水平旋转 45 度 // size: 输出图片边长正方形 // bg: 背景色传 Color.clear 得到透明背景 public static void Generate(GameObject modelPrefab, Vector3 angle, int size, Color bg, string savePath) { // 1. 实例化到场景外避免影响当前场景 GameObject instance Object.Instantiate(modelPrefab); instance.transform.position new Vector3(10000, 10000, 10000); // 2. 调用运行时预览生成器指定尺寸、背景和旋转 Texture2D tex RuntimePreviewGenerator.GenerateModelPreview( instance.transform, size, size, bg, angle); // 3. 编码成 PNG 并写入磁盘 byte[] bytes tex.EncodeToPNG(); File.WriteAllBytes(savePath, bytes); // 4. 清理防止内存泄漏 Object.DestroyImmediate(instance); Object.DestroyImmediate(tex); } }逻辑说明第一步把模型挪到远离原场景的位置是为了避免它和场景里已有物体互相遮挡这是批量出图时最容易忽略的一步。第二步的GenerateModelPreview是核心它内部会临时创建相机和 RenderTexture根据模型包围盒自动算好取景angle参数直接决定观察方向。第三步EncodeToPNG把纹理转成字节流注意这一步要在渲染完成后调用否则可能拿到空图。第四步必须销毁实例和纹理批量跑几百个模型时不清理内存会一路涨到崩。参数说明size建议用 2 的幂比如 256、512某些压缩格式对非 2 的幂不友好bg传Color.clear得到透明背景传Color.white得到白底做图鉴一般用透明angle是欧拉角想同时看俯视就改 x 分量比如new Vector3(30, 45, 0)。3.3 批量出多视角图的循环写法单个模型跑通后批量多视角就是套一层循环。下面这段是我给美术出三视图时用的。// 三个标准视角正面、侧面、45 度 Vector3[] angles new Vector3[] { new Vector3(0, 0, 0), // 正面 new Vector3(0, 90, 0), // 侧面 new Vector3(0, 45, 0) // 45 度 }; foreach (var prefab in prefabs) { foreach (var angle in angles) { string name ${prefab.name}_{angle.y}.png; string path Path.Combine(outputDir, name); ModelThumbnail.Generate(prefab, angle, 512, Color.clear, path); } }逻辑说明外层遍历模型内层遍历角度文件名用模型名加角度后缀方便后续按名字检索。这里有个细节GenerateModelPreview每次调用都会创建临时相机连续调用之间最好让渲染完成如果发现出图错位可以在循环里加一帧等待。参数说明outputDir要提前用Directory.CreateDirectory确保存在否则File.WriteAllBytes会直接抛异常角度数组可以按项目需求扩展成八个方向。3.4 出图后怎么验证生成完不要直接交付先抽查。我一般会写个简单的校验读回 PNG 的尺寸是否等于设定值像素是否全透明全透明说明模型没渲染进去。全透明最常见的原因是模型包围盒计算异常比如 SkinnedMeshRenderer 在未播放动画时包围盒是空的需要先调用SkinnedMeshRenderer.BakeMesh或者手动指定 bounds。4. 避坑与排查出图黑屏、透明、错位的真实原因4.1 出图全黑现象生成的 PNG 打开是全黑或者全灰。原因通常是渲染时相机没有正确清除背景或者光照缺失导致模型全暗。解决确认bg参数传了有效颜色透明背景要确保渲染管线支持 alpha模型全暗则是在预览环境里没有光源RuntimePreviewGenerator 一般会自带环境光设置如果没有需要手动加一个方向光或者提高环境光强度。4.2 出图全透明现象图片尺寸对但内容什么都没有。原因多半是模型包围盒为空相机算出来的取景范围是零。解决对 SkinnedMeshRenderer渲染前先烘焙网格对普通 MeshRenderer检查模型是否被禁用或者缩放为零。我踩过一次预制体上的模型子物体被 SetActive(false)实例化后自然渲染不出来。4.3 模型被裁切或只占一角现象模型缺了一半或者缩在图片角落。原因是相机距离和正交范围没算对。解决RuntimePreviewGenerator 会自动算包围盒但如果模型带有粒子或者拖尾这种超出包围盒的组件就会被裁。这种情况要么手动扩大 padding要么把特效组件临时禁用再出图。4.4 批量跑内存暴涨现象跑几十个模型后 Unity 卡死或崩溃。原因是每次生成的 Texture2D 和临时 RenderTexture 没释放。解决严格按前面的封装用完DestroyImmediate销毁纹理和实例如果是在编辑器里批量跑可以每隔若干个模型调用一次Resources.UnloadUnusedAssets。4.5 打包后报类型找不到现象编辑器里一切正常打包成运行时版本后报找不到 RuntimePreviewGenerator。原因是程序集定义没被正确引用或者该模块被放进了 Editor 目录。解决确认RuntimePreviewGenerator.Runtime.asmdef所在目录不在 Editor 下并在调用方程序集的引用列表里加上它。5. 进阶技巧把出图接进自动化管线并做质量校验跑通之后真正省时间的是把它接进自动化。我现在的习惯是写一个编辑器菜单项选中一批预制体一键出图到指定目录同时生成一份清单记录每个模型对应的文件名和角度。更进一步可以在 CI 里跑一个批处理每次模型更新后自动重出图标避免美术改了模型图标还是旧的。质量校验这块除了前面说的尺寸和透明度检查我还会做一步「非空像素占比」统计把 PNG 读回来统计非透明像素占总像素的比例如果低于某个阈值比如 5%说明模型太小或者根本没渲染出来直接标记为异常。这个检查帮我拦下过好几次包围盒算错的问题。// 简单的非空像素占比校验 Texture2D tex new Texture2D(2, 2); tex.LoadImage(File.ReadAllBytes(path)); Color[] pixels tex.GetPixels(); int solid 0; foreach (var p in pixels) { if (p.a 0.01f) solid; } float ratio (float)solid / pixels.Length; if (ratio 0.05f) { Debug.LogWarning($图片可能异常: {path}, 非空占比 {ratio:P}); }逻辑说明LoadImage把磁盘上的 PNG 读回纹理遍历像素统计 alpha 大于阈值的数量占比过低就告警。参数说明阈值 0.05 是经验值模型特别细长时可以调低图标类一般不会低于这个数。还有一个容易忽略的点是方向和大小的组合。想要「任意控制方向」本质是把欧拉角当成参数传进去但要注意 Unity 的欧拉角顺序和模型自身朝向。有些模型导入时朝向是 Z 轴向前有些是 Y 轴向上出图前最好先确认模型的 forward 方向否则你以为的正面其实是背面。我一般会先出一个 0 度图看一眼确认朝向对了再批量跑。从那以后我每次接模型出图需求都强制先跑一个单模型三视角验证朝向和包围盒确认没问题再上批量。这套流程帮我省下了大量返工时间。希望帮到你。本文还有配套的精品资源点击获取