Project视图里的prefab文件都是一个蓝色的正方体,我想给它们加个预览图,暂时不知道怎么改Project视图的,但反正我想像NGUI那样有个专门的窗口存放一些常用的prefab,所以做成了如下效果:

关于如何定制窗口,可以参考雨松的教程:Unity3D研究院之拓展自定义编辑器窗口

实现思路:
主要参考自:获取unity prefab的预览图像

unity在2017.2版本可以使用官方自带API:AssetPreview.GetAssetPreview(Object m) as Texture,但此版本前此接口用于有子节点的prefab是无效的,所以只好自己动手:

实例化该prefab,创建摄像机调好参数并Render to texture保存为图片,最后删掉生成的节点毁尸灭迹。但里面只实现了3D prefab的,对于UGUI是无效的,因为UGUI节点需要放在Canvas里才行,而且计算它们包围盒的算法也不同,所以我对此做了扩展:

public static Texture GetAssetPreview(GameObject obj)
{GameObject canvas_obj = null;GameObject clone = GameObject.Instantiate(obj);Transform cloneTransform = clone.transform;bool isUINode = false;if (cloneTransform is RectTransform){//如果是UGUI节点的话就要把它们放在Canvas下了canvas_obj = new GameObject("render canvas", typeof(Canvas));Canvas canvas = canvas_obj.GetComponent<Canvas>();cloneTransform.parent = canvas_obj.transform;cloneTransform.localPosition = Vector3.zero;canvas_obj.transform.position = new Vector3(-1000, -1000, -1000);canvas_obj.layer = 21;//放在21层,摄像机也只渲染此层的,避免混入了奇怪的东西isUINode = true;}elsecloneTransform.position = new Vector3(-1000, -1000, -1000);Transform[] all = clone.GetComponentsInChildren<Transform>();foreach (Transform trans in all){trans.gameObject.layer = 21;}Bounds bounds = GetBounds(clone);Vector3 Min = bounds.min;Vector3 Max = bounds.max;GameObject cameraObj = new GameObject("render camera");Camera renderCamera = cameraObj.AddComponent<Camera>();renderCamera.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 1f);renderCamera.clearFlags = CameraClearFlags.Color;renderCamera.cameraType = CameraType.Preview;renderCamera.cullingMask = 1 << 21;if (isUINode){cameraObj.transform.position = new Vector3((Max.x + Min.x) / 2f, (Max.y + Min.y) / 2f, cloneTransform.position.z-100);Vector3 center = new Vector3(cloneTransform.position.x, (Max.y + Min.y) / 2f, cloneTransform.position.z);cameraObj.transform.LookAt(center);renderCamera.orthographic = true;float width = Max.x - Min.x;float height = Max.y - Min.y;float max_camera_size = width > height ? width : height;renderCamera.orthographicSize = max_camera_size / 2;//预览图要尽量少点空白}else{cameraObj.transform.position = new Vector3((Max.x + Min.x) / 2f, (Max.y + Min.y) / 2f, Max.z + (Max.z - Min.z));Vector3 center = new Vector3(cloneTransform.position.x, (Max.y + Min.y) / 2f, cloneTransform.position.z);cameraObj.transform.LookAt(center);int angle = (int)(Mathf.Atan2((Max.y - Min.y) / 2, (Max.z - Min.z)) * 180 / 3.1415f * 2);renderCamera.fieldOfView = angle;}RenderTexture texture = new RenderTexture(128, 128, 0, RenderTextureFormat.Default);renderCamera.targetTexture = texture;Undo.DestroyObjectImmediate(cameraObj);Undo.PerformUndo();//不知道为什么要删掉再Undo回来后才Render得出来UI的节点,3D节点是没这个问题的,估计是Canvas创建后没那么快有效?renderCamera.RenderDontRestore();RenderTexture tex = new RenderTexture(128, 128, 0, RenderTextureFormat.Default);Graphics.Blit(texture, tex);Object.DestroyImmediate(canvas_obj);Object.DestroyImmediate(cameraObj);return tex;
}public static Bounds GetBounds(GameObject obj)
{Vector3 Min = new Vector3(99999, 99999, 99999);Vector3 Max = new Vector3(-99999, -99999, -99999);MeshRenderer[] renders = obj.GetComponentsInChildren<MeshRenderer>();if (renders.Length > 0){for (int i = 0; i < renders.Length; i++){if (renders[i].bounds.min.x < Min.x)Min.x = renders[i].bounds.min.x;if (renders[i].bounds.min.y < Min.y)Min.y = renders[i].bounds.min.y;if (renders[i].bounds.min.z < Min.z)Min.z = renders[i].bounds.min.z;if (renders[i].bounds.max.x > Max.x)Max.x = renders[i].bounds.max.x;if (renders[i].bounds.max.y > Max.y)Max.y = renders[i].bounds.max.y;if (renders[i].bounds.max.z > Max.z)Max.z = renders[i].bounds.max.z;}}else{RectTransform[] rectTrans = obj.GetComponentsInChildren<RectTransform>();Vector3[] corner = new Vector3[4];for (int i = 0; i < rectTrans.Length; i++){//获取节点的四个角的世界坐标,分别按顺序为左下左上,右上右下rectTrans[i].GetWorldCorners(corner);if (corner[0].x < Min.x)Min.x = corner[0].x;if (corner[0].y < Min.y)Min.y = corner[0].y;if (corner[0].z < Min.z)Min.z = corner[0].z;if (corner[2].x > Max.x)Max.x = corner[2].x;if (corner[2].y > Max.y)Max.y = corner[2].y;if (corner[2].z > Max.z)Max.z = corner[2].z;}}Vector3 center = (Min + Max) / 2;Vector3 size = new Vector3(Max.x - Min.x, Max.y - Min.y, Max.z - Min.z);return new Bounds(center, size);
}

最后加上保存Texture为本地图片的:

public static bool SaveTextureToPNG(Texture inputTex, string save_file_name)
{RenderTexture temp = RenderTexture.GetTemporary(inputTex.width, inputTex.height, 0, RenderTextureFormat.ARGB32);Graphics.Blit(inputTex, temp);bool ret = SaveRenderTextureToPNG(temp, save_file_name);RenderTexture.ReleaseTemporary(temp);return ret;
}//将RenderTexture保存成一张png图片
public static bool SaveRenderTextureToPNG(RenderTexture rt, string save_file_name)
{RenderTexture prev = RenderTexture.active;RenderTexture.active = rt;Texture2D png = new Texture2D(rt.width, rt.height, TextureFormat.ARGB32, false);png.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);byte[] bytes = png.EncodeToPNG();string directory = Path.GetDirectoryName(save_file_name);if (!Directory.Exists(directory))Directory.CreateDirectory(directory);FileStream file = File.Open(save_file_name, FileMode.Create);BinaryWriter writer = new BinaryWriter(file);writer.Write(bytes);file.Close();Texture2D.DestroyImmediate(png);png = null;RenderTexture.active = prev;return true;
}

详细功能和代码请看: UGUI界面编辑器扩展集合

Unity编辑器扩展-生成prefab的预览图并保存为图片相关推荐

  1. 旋转狗头:Python如何读取STL文件,生成STL文件预览图(缩略图)之进化,动态旋转Gif图

    之前的文章<Python如何读取STL文件,生成STL文件预览图(缩略图)>实现了将STL文件读取加载.绘制保存为某个角度下2D的png图片,作为预览图(缩略图).但是3D转2D,预览就丢 ...

  2. Python如何读取STL文件,生成STL文件预览图(缩略图)

    如果你的项目也遇到了需要在后台将STL文件自动处理并生成预览图(缩略图)的需求,那么看本文就可以实现.如下图,我有一个狗头. 后台处理后生成的效果1: 后台处理后生成的效果2: 后台处理后生成的效果3 ...

  3. v-viewer预览图的使用(图片预览旋转/放大缩小/上下切换等)

    前言: 之前项目需求,需要找一个预览图的组件,最开始,找了vue-preview组件.因为vue-preview是直接引入 < vue-preview>这个标签,无法看到对组件里面的图片i ...

  4. 在线画时序图的工具:Web Sequence Diagrams ,支持实时生成预览图

    因为工作需要,这两天在尝试着给手里壹些模块画时序图(Sequence Diagrams),壹般画这种图的时候,我们第壹反应会想到安装 IBM 的 Rational Rose,但是我不想为了画这种图就去 ...

  5. java 视频预览_java在上传视频时生成预览图

    在圣品上传时往往需要生成一张预览图(缩略图),如果在非特殊情况下让用户单独上传,会造成工作压力,此时可以用视频中某一帧作为封面图,实现方式如下: public class ImageUtil { /* ...

  6. 微信小程序-图片预览图

    有时候图片列表图片过小看不清图片内容,这时我们一般就希望点击图片可以放大显示进行预览,那么,接下来我们就调用微信原生API的的浏览图片程序进行对图片预览的实现. 单张图片预览 通过微信原生API实现单 ...

  7. 【Unity编辑器扩展】(二)PSD转UGUI Prefab, 图层解析和碎图导出

    书接上回:[Unity编辑器扩展](一)PSD转UGUI Prefab, Aspose.PSD和Harmony库的使用_TopGames的博客-CSDN博客 工具使用预览: 工具目标: 1. 实现将p ...

  8. 【Unity编辑器扩展】(三)PSD转UGUI Prefab, 一键拼UI解放美术/程序(完结)

    工具效果: 第一步,把psd图层转换为可编辑的节点树,并自动解析UI类型.自动绑定UI子元素: 第二步, 点击"生成UIForm"按钮生成UI预制体 (若有UI类型遗漏可在下拉菜单 ...

  9. 【Unity编辑器扩展】(一)PSD转UGUI Prefab, Aspose.PSD和Harmony库的使用

    [Unity编辑器扩展](二)PSD转UGUI Prefab, 图层解析和碎图导出_psd导入unity_TopGames的博客-CSDN博客 [Unity编辑器扩展](三)PSD转UGUI Pref ...

最新文章

  1. Adam真的是最好的优化器吗?
  2. 绩效面谈的细节,阿里巴巴是如何做的?
  3. C++拓展笔记2-3:C++中this指针用法简介
  4. 【浙大软件学院机试】深度优先搜索、并查集和优先级队列知识点(Python实现)
  5. 【pyqt5学习】——containers相关控件(tab widget、scroll area、stack widget、tool box、MDI area、dock widget)
  6. 树形DP+树状数组 HDU 5877 Weak Pair
  7. 散点画三维曲面图_UG 复杂曲面合金零件的数控加工
  8. 半夜闲的真是蛋疼。。。决定写个小博文
  9. 95-872-060-源码-CEP-匹配事件提取
  10. 支付宝澄清使用华为方舟编译器;三星苹果遭遇集体诉讼;PHP 7.4.0 beta4 发布 | 极客头条...
  11. 简单分享apache封IP的方法
  12. Ubuntu各个版本国内源
  13. (cljs/run-at (JSVM. :all) 细说函数) 1
  14. 恐龙机器人钢索恐龙形态_?四川自贡发现距今1.6亿年恐龙化石 已运抵自贡恐龙博物馆...
  15. 详解:路由器性能的各项指标
  16. [编程开发工具-7]:四款功能强大的代码比较工具:Araxis Merge、Beyond compare、DiffMerge、WinMerge
  17. java简历 star_写简历时的STAR法则
  18. 数据文件offline online
  19. 静雅学校有高中吗有计算机,涿州靖雅中学
  20. foxmai邮件服务器pop,全球邮企业邮箱Foxmail POP3/IMAP协议设置方法

热门文章

  1. yolov5 代码内容解析
  2. VB数据库方面的知识
  3. 高中新课程作业本 地理 必修1 参考答案下
  4. 爱思国际获戈壁创投数百万美元Pre-A 轮融资,意做菲律宾的分众传媒
  5. java自动化word报告
  6. 当大叔爱上小萝莉我就爱上了正则表达式(一)
  7. 【计算机体系结构】非线性流水线调度算法 C++ Python
  8. 三文鱼肉质和虹鳟鱼肉质有什么区别差异
  9. 学生问我25-30K得面试题能不能帮忙,这我不得上,爬取某网站电影视频内容
  10. 佳博pt380便携式小票打印机,win10安装