强大的Unity编辑器扩展

有的同学可能会问:模型制作好,在模型设置里先解压贴图,再解压材质不就行了?
当然可以,不过现在解决的是模型没有贴图,贴图都是在SP里做的,导出来都是单独的贴图,不会直接和模型绑定
总之,你自己一个一个往材质球上贴也没啥问题,我是觉得贴的太痛苦了,来一个模型我得拿来贴贴贴…贴个der.
编辑器扩展就能解决很多手动的问题.

先看效果:

材质球会自动匹配贴图

匹配贴图时需要注意:

贴图名称必须是:模型名称_材质球名称_贴图类型

属性介绍
  • 模型路径:把模型拖入会自动识别路径
  • 贴图后缀:类似_Albedo或者_Occlusion,有的同学喜欢这样命名,AL,AO,所以开放出来自定义
  • 导出材质球:模型存在的目录会自动创建Material文件夹,未解压材质的模型将会把材质解压到此文件夹
  • 设置材质:根据模型与材质球的名称自动匹配贴图
SP导出流程:

文件 - 导出贴图 - 配置里需要这样命名

其中:
  • $project是当前SP项目名称(用不到)
  • $mesh是模型名称
  • $textureSet是材质球名称

代码介绍:

属性这里可以修改默认后缀

[SerializeField]public string m_Albedo = "_Albedo", m_Metallic = "_Metallic", m_NormalMap = "_Normal", m_HeightMap = "_Height", m_OcclusionMap = "_Occlusion";

这里设置名称规则:objName + “_” + mat.name + m_Albedo,可以自行修改

void setMaterialShader(string path){Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);string[] allPath = GetObjPath("Texture2D");for (int i = 0, len = allPath.Length; i < len; i++){string filePath = AssetDatabase.GUIDToAssetPath(allPath[i]);Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(filePath);string objName = Path.GetFileName(modelPath);objName = objName.Substring(0, objName.Length - 4);if (t.name == objName + "_" + mat.name + m_Albedo){mat.SetTexture(Albedo, t);}else if (t.name == objName + "_" + mat.name + m_HeightMap){mat.SetTexture(HeightMap, t);}else if (t.name == objName + "_" + mat.name + m_Metallic){mat.SetTexture(Metallic, t);}else if (t.name == objName + "_" + mat.name + m_NormalMap){mat.SetTexture(NormalMap, t);}else if (t.name == objName + "_" + mat.name + m_OcclusionMap){mat.SetTexture(OcclusionMap, t);}else{Debug.Log(mat.name+"材质球无法匹配:" + t.name);}}}
完整代码:

这个代码继承EditorWindow
所以必须放在Editor文件夹下, 制作旋转门与相机控制器也是一样,都是用的编辑器扩展技术

using System.IO;
using UnityEngine;
using UnityEditor;public class MatchinMaterial_Editor : EditorWindow
{public string modelPath = "Assets";public Rect modelRect;public string Albedo = "_MainTex";public string Metallic = "_MetallicGlossMap";public string NormalMap = "_BumpMap";public string HeightMap = "_ParallaxMap";public string OcclusionMap = "_OcclusionMap";private static MatchinMaterial_Editor _window;[SerializeField]public string m_Albedo = "_Albedo", m_Metallic = "_Metallic", m_NormalMap = "_Normal", m_HeightMap = "_Height", m_OcclusionMap = "_Occlusion";[MenuItem("Tools/材质匹配")]public static void showWindow(){Rect wr = new Rect(0, 0, 300, 300);// true 表示不能停靠的_window = (MatchinMaterial_Editor)GetWindowWithRect(typeof(MatchinMaterial_Editor), wr, true, "材质匹配");_window.Show();}public void OnGUI(){EditorGUILayout.Space();EditorGUILayout.LabelField("模型路径 (鼠标拖拽文件夹到这里)");EditorGUILayout.Space();GUI.SetNextControlName("input1");//设置下一个控件的名字modelRect = EditorGUILayout.GetControlRect();modelPath = EditorGUI.TextField(modelRect, modelPath);EditorGUILayout.Space();m_Albedo = EditorGUILayout.TextField("Albedo图片后缀", m_Albedo);m_Metallic = EditorGUILayout.TextField("Metallic图片后缀", m_Metallic);m_NormalMap = EditorGUILayout.TextField("NormalMap图片后缀", m_NormalMap);m_HeightMap = EditorGUILayout.TextField("HeightMap图片后缀", m_HeightMap);m_OcclusionMap = EditorGUILayout.TextField("OcclusionMap图片后缀", m_OcclusionMap);DragFolder();EditorGUILayout.Space();// 导出材质if (GUILayout.Button("导出材质球")){ForEachModels();}EditorGUILayout.Space();if (GUILayout.Button("设置材质")){ForEachMaterials();}}/// <summary>/// 获得拖拽文件/// </summary>void DragFolder(){//鼠标位于当前窗口if (mouseOverWindow == this){//拖入窗口未松开鼠标if (Event.current.type == EventType.DragUpdated){DragAndDrop.visualMode = DragAndDropVisualMode.Generic;//改变鼠标外观// 判断区域if (modelRect.Contains(Event.current.mousePosition))GUI.FocusControl("input1");}//拖入窗口并松开鼠标else if (Event.current.type == EventType.DragExited){string dragPath = string.Join("", DragAndDrop.paths);// 判断区域if (modelRect.Contains(Event.current.mousePosition))this.modelPath = dragPath;// 取消焦点(不然GUI不会刷新)GUI.FocusControl(null);}}}/// <summary>/// 导出材质/// </summary>void ForEachModels(){string[] allPath = AssetDatabase.FindAssets("t:GameObject", new string[] { modelPath });//Debug.Log("-- allPath: " + allPath.Length);for (int i = 0, len = allPath.Length; i < len; i++){string filePath = AssetDatabase.GUIDToAssetPath(allPath[i]);// 设置模型ExtractMaterialsFromFBX(filePath);}// 如果选取的是FBX模型文件if (allPath.Length == 0){if (Path.GetExtension(modelPath) == ".fbx"){ExtractMaterialsFromFBX(modelPath);}else{Debug.LogError("当前选择目录未找到FBX文件: " + this.modelPath);}}}/// <summary>/// 导出材质球/// </summary>/// <param name="assetPath"></param>public void ExtractMaterialsFromFBX(string assetPath){// 材质目录string materialFolder = Path.GetDirectoryName(assetPath) + "/Material";//Debug.Log(assetPath); // 如果不存在该文件夹则创建一个新的if (!AssetDatabase.IsValidFolder(materialFolder))AssetDatabase.CreateFolder(Path.GetDirectoryName(assetPath), "Material");// 获取 assetPath 下所有资源。Object[] assets = AssetDatabase.LoadAllAssetsAtPath(assetPath);foreach (Object item in assets){if (item.GetType() == typeof(Material)){string path = System.IO.Path.Combine(materialFolder, item.name) + ".mat";// 为资源创建一个新的唯一路径。path = AssetDatabase.GenerateUniqueAssetPath(path);// 通过在导入资源(例如,FBX 文件)中提取外部资源,在对象(例如,材质)中创建此资源。string value = AssetDatabase.ExtractAsset(item, path);// 成功提取( 如果 Unity 已成功提取资源,则返回一个空字符串)if (string.IsNullOrEmpty(value)){AssetDatabase.WriteImportSettingsIfDirty(assetPath);AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);Debug.Log(Path.GetFileName(assetPath) + " 的 Material 导出成功!!");}}}}/// <summary>/// 得到所有材质球/// </summary>void ForEachMaterials(){string[] allPath = GetObjPath("Material");for (int i = 0, len = allPath.Length; i < len; i++){string filePath = AssetDatabase.GUIDToAssetPath(allPath[i]);setMaterialShader(filePath);}Debug.Log("Material Shader 设置完成, 一共: " + allPath.Length + "个");}void setMaterialShader(string path){Material mat = AssetDatabase.LoadAssetAtPath<Material>(path);string[] allPath = GetObjPath("Texture2D");for (int i = 0, len = allPath.Length; i < len; i++){string filePath = AssetDatabase.GUIDToAssetPath(allPath[i]);Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(filePath);string objName = Path.GetFileName(modelPath);objName = objName.Substring(0, objName.Length - 4);if (t.name == objName + "_" + mat.name + m_Albedo){mat.SetTexture(Albedo, t);}else if (t.name == objName + "_" + mat.name + m_HeightMap){mat.SetTexture(HeightMap, t);}else if (t.name == objName + "_" + mat.name + m_Metallic){mat.SetTexture(Metallic, t);}else if (t.name == objName + "_" + mat.name + m_NormalMap){mat.SetTexture(NormalMap, t);}else if (t.name == objName + "_" + mat.name + m_OcclusionMap){mat.SetTexture(OcclusionMap, t);}else{Debug.Log(mat.name+"材质球无法匹配:" + t.name);}}}string[] GetObjPath(string mType){//string path = Path.GetDirectoryName(modelPath) + "/Material";//得到此物体的文件目录,具体到Material文件string path = Path.GetDirectoryName(modelPath);//得到此物体的文件目录return AssetDatabase.FindAssets("t:"+ mType, new string[] { path });//在这个文件下找"t:Material"这个文件}
}

这个代码需要Demo演示?

Unity 贴图自动匹配材质工具 贴图自动添加到材质球工具 材质球匹配贴图工具 Substance Painter制作的贴图自动匹配材质球工具相关推荐

  1. 分享基本书,Unity Shader入门精要、PBR_Guide_Vol1_中文版、PBR_Guide_Vol2_中文版、PBR守望先锋猎风, substance painter制作

    Unity Shader入门精要 PBR_Guide_Vol1_中文版 PBR_Guide_Vol2_中文版 PBR守望先锋猎风, substance painter制作 百度链接,自取 链接:htt ...

  2. 使用Substance Painter烘焙服饰贴图

    由于渲染时需要高模,为了同时大量高模导入,加上防止模型的遮挡影响贴图,尽量把模型拆开成几部分单独渲染,这样一旦出现问题,也可以单独渲染,本次分成两部分渲染: 为了方便管理,最好建好文件夹: 导出前记得 ...

  3. Substance Painter里 AO贴图 烘焙黑图 原因

    检查: 1高低模 输入对了吗?反了,错了? 2高模在  max /maya 里相对低模,没有位移和缩放,否则烘焙时候,高低模对不上,会黑(我是这个原因,不小心缩放了) 3材质,是不是用了一个材质,如果 ...

  4. Substance Painter材质导入unity渲染通道配置更改

    substance painter是工作在线性空间下的, unity 3d如果是工作在线性空间下的话要注意 substance painter导出的贴图Albedo要勾选sRGB选项,Mask贴图不需 ...

  5. Substance Painter 2018 Mac(次世代游戏贴图绘制软件) v2018.3.2破解版

    Substance Painter 2018 Mac 中文破解版是macOS平台上最出色的次世代游戏贴图绘制软件,具有一些非常新奇的功能,比如粒子笔刷,可以模拟自然粒子下落,粒子的轨迹形成纹理.Sub ...

  6. Substance Designer油画风格贴图实例制作视频教程

    Substance Designer油画风格贴图实例制作视频教程 本教程是关于Substance Designer油画风格贴图实例制作视频教程,时长:1小时20分,大小:1.1 GB,MP4高清视频格 ...

  7. 举个栗子!Tableau技巧(32):快速制作标靶图(靶心图)

    什么情况下使用标靶图? 参照目标评估指标表现.例如:销售配额评估.实际花费与预算的比较情况.绩效优劣范围( 优/良/差). 那么如何简单.快速的制作一个类似的标靶图呢? 本期<举个栗子>, ...

  8. Unity高级功能—法线贴图的制作以及在代码里面进行材质上贴图的切换

    制作法线贴图还是得美术提供你几张基础的法线贴图之后,然后再去制作. 现在我们手里有两张贴图,一张是正常贴图,一张是法线贴图: 1.选择美术提供的基础的法线贴图: Tip:其中Filtering选项有的 ...

  9. Unity 自动制作LowPoly随机形态的树预制体工具

    通过一个树干模型和树叶模型 随机制作不同的预制体 Editor脚本: //===================================================== // - File ...

  10. 最新 unity 血条的另类制作-伤害减血加血自动回血

    最新 unity 血条的另类制作-伤害减血加血自动回血 血条的另类制作-伤害减血加血,最简单教程,菜鸟必看 血条的效果图: 做这个教程的目的,第一是为了巩固自己学到的知识,同时也可以帮助和我一起正在学 ...

最新文章

  1. Linux服务名重命名
  2. 红盟过客提到的 CCIE 必读书籍
  3. NDK 交叉编译常用变量
  4. 三线调速风扇原理_学修电风扇~风机转速慢、调速失灵故障维修。
  5. 基于tcp connect的端口扫描程序
  6. mysql 日志_MySQL日志系统
  7. 'parent.relativePath' points at no local POM
  8. 计算机信息处理工具教案设计,《信息和信息处理工具》教案设计
  9. java list打乱排序_JAVA Collections.shuffle打乱列表
  10. Unix网络编程---第三次作业
  11. 使用ocupload和POI一键上传Excel并解析导入数据库
  12. 技术人员的会议优化记录
  13. 「大数据成神之路」第四版更新完毕
  14. Linux网卡驱动(4)—DM9000网卡驱动程序完全分析
  15. 我的毕业生涯至从零开始从事编程开发
  16. 二行代码解决全部网页木马(含iframe/script木马)
  17. 【Unity】 HTFramework框架(十四)Audio音频管理器
  18. 第3章 数据分析工具Pandas
  19. 网站后台——用户上传图片剪切
  20. 《C primer plus》——文件输入/输出

热门文章

  1. 数据仓库与数据挖掘 4(上)
  2. 计算机应用基础项目化教程ppt,计算机应用基础项目化教程_课件
  3. 1颜色原理及数字图片原理
  4. 25.构造ICMP数据包
  5. matlab gui系统设计,matlabgui系统设计
  6. CuteFTP下载大文件时报错
  7. Windows 8 平板电脑体验及思考
  8. linux用sqlserver数据库,Linux下安装访问SQLSERVER2000数据库(附文件下载)
  9. 联想计算机M.2固态银盘,联想ThinkPad T14拆机加装内存和M.2固态硬盘
  10. java的property_「propertyutils」java之PropertyUtils - seo实验室