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

强大的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演示?

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
Unity中的材质贴图是用来控制物体的外观和质感的。材质(Material)定义了物体看起来是什么做的,而贴图(Texture)则是材质的一部分,用于给物体表面添加纹理和颜色。着色器(Shader)是一小段程序,负责将输入的网格以指定的方式和输入的贴图或者颜色等组合作用,输出最终的渲染结果。 Unity中的材质文件后缀名为.mat,你可以在Assets中建立“Materials”文件夹来存放材质。在创建材质后,你可以编辑其属性,如调整颜色、透明度、光照反射等。然后,直接将材质拖放到物体上,即可应用该材质贴图材质的一部分,用于给物体表面添加纹理和颜色。你可以在Assets中建立“Textures”文件夹来存放贴图贴图文件可以是常见的图片格式,如.jpg、.png等。在编辑材质时,你可以将贴图文件拖放到相应的属性上,从而将纹理和颜色应用到物体表面。 在使用贴图时,你可以使用tiling缩放来调整贴图在物体表面的重复次数。通过改变tiling的值,你可以控制贴图在UV坐标上的缩放倍数,从而调整贴图的大小和密度。 总结来说,Unity中的材质贴图是用来控制物体外观和质感的重要组成部分。材质定义了物体看起来是什么做的,而贴图则用于给物体表面添加纹理和颜色。你可以在Assets中创建“Materials”和“Textures”文件夹来方便地管理材质贴图。编辑材质时,可以调整其属性和应用贴图文件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Unity3D超700+材质&贴图](https://download.csdn.net/download/jhcht/10386117)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Unity3D基础3:贴图材质](https://blog.csdn.net/Jaihk662/article/details/86746756)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [【瑞模网】Unity3D基础:贴图材质](https://blog.csdn.net/rrmod/article/details/128883169)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐沢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值