处理导入默认材质球

  1. 在资源导入后处理分配模型材质球地方进行替换成项目中的
  2. 需要处理以下细节
    • 在材质球还没有导入的时候是无法加载出材质球的
    • 动态创建材质球与shader,文件的guid必须固化,否则svn更新冲突可能会导致资源引用丢失

代码如下:

using System;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;

/// <summary>
/// 模型默认材质球替换
/// </summary>
public class ModelDefaultMaterialReplacer : AssetPostprocessor
{
    private const string MAT_PATH = "Assets/XCore/Material/Default_Model.mat";
    private const string SHADER_PATH = "Assets/Resources/Shader/XCore/ModeDefault.shader";
    private const string SHADER_GUID = "b527cdf8848d02349a7a0ad46b491d7e";
    private const string SHADER_FIND_PATH = "Legacy Shaders/ModeDefault";

    private Material OnAssignMaterialModel(Material material, Renderer renderer)
    {
        material = AssetDatabase.LoadAssetAtPath<Material>(MAT_PATH);

        if (material == null)
        {
            //创建shader
            bool createdShader = false;
            Shader shader = AssetDatabase.LoadAssetAtPath<Shader>(SHADER_PATH);
            if (shader == null)
            {
                shader = Shader.Find("Unlit/Color");
                createdShader = true;
                string shaderFullPath = Application.dataPath + SHADER_PATH.Substring(6);
                if (!Directory.Exists(Path.GetDirectoryName(SHADER_PATH)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(SHADER_PATH));
                }

                //生成shader内容
                StringBuilder shaderContent = new StringBuilder();
                shaderContent.AppendLine("Shader \""+ SHADER_FIND_PATH + "\"");
                shaderContent.AppendLine("{");
                shaderContent.AppendLine("    SubShader");
                shaderContent.AppendLine("    {");
                shaderContent.AppendLine("        Pass");
                shaderContent.AppendLine("        {");
                shaderContent.AppendLine("            CGPROGRAM");
                shaderContent.AppendLine("            #pragma vertex vert");
                shaderContent.AppendLine("            #pragma fragment frag");
                shaderContent.AppendLine("            float4 vert(float4 v : POSITION) : SV_POSITION");
                shaderContent.AppendLine("            {");
                shaderContent.AppendLine("                return UnityObjectToClipPos(v);");
                shaderContent.AppendLine("            }");
                shaderContent.AppendLine("            fixed4 frag() : SV_Target");
                shaderContent.AppendLine("            {");
                shaderContent.AppendLine("                return fixed4(1.0,1.0,1.0,1.0);");
                shaderContent.AppendLine("            }");
                shaderContent.AppendLine("            ENDCG");
                shaderContent.AppendLine("        }");
                shaderContent.AppendLine("    }");
                shaderContent.AppendLine("}");

                File.WriteAllText(shaderFullPath, shaderContent.ToString());

                //生成meta
                StringBuilder metaContent = new StringBuilder();
                metaContent.AppendLine("fileFormatVersion: 2");
                metaContent.AppendLine("guid: " + SHADER_GUID);
                metaContent.AppendLine("ShaderImporter:");
                metaContent.AppendLine("  externalObjects: {}");
                metaContent.AppendLine("  defaultTextures: []");
                metaContent.AppendLine("  nonModifiableTextures: []");
                metaContent.AppendLine("  userData:");
                metaContent.AppendLine("  assetBundleName:");
                metaContent.AppendLine("  assetBundleVariant:");
                File.WriteAllText(shaderFullPath + ".meta", metaContent.ToString());

                AssetDatabase.ImportAsset(SHADER_PATH);
            }

            //创建材质球
            string matFullPath = Application.dataPath + MAT_PATH.Substring(6);
            if (File.Exists(matFullPath))
            {
                File.Delete(matFullPath);
            }

            if (!Directory.Exists(Path.GetDirectoryName(matFullPath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(matFullPath));
            }

            material = new Material(shader);
            AssetDatabase.CreateAsset(material, MAT_PATH);
            if(createdShader)
            {
                //替换材质球shader引用
                string text = File.ReadAllText(matFullPath);
                int startIndex = text.IndexOf("m_Shader:", StringComparison.Ordinal);
                int endIndex = text.IndexOf('\n', startIndex);
                string a = text.Substring(0, startIndex);
                string b = text.Substring(endIndex);
                text = a + "m_Shader: {fileID: 4800000, guid: " + SHADER_GUID + ", type: 3}" + b;

                startIndex = text.IndexOf("m_Name:", StringComparison.Ordinal);
                endIndex = text.IndexOf('\n', startIndex);
                a = text.Substring(0, startIndex);
                b = text.Substring(endIndex);
                text = a + "m_Name: " + Path.GetFileNameWithoutExtension(SHADER_PATH) + b;

                File.WriteAllText(matFullPath, text);

                //替换meta
                StringBuilder metaContent = new StringBuilder();
                metaContent.AppendLine("fileFormatVersion: 2");
                metaContent.AppendLine("guid: cb1bec2b350b9b34794f8f7df820020a");
                metaContent.AppendLine("NativeFormatImporter:");
                metaContent.AppendLine("  externalObjects: {}");
                metaContent.AppendLine("  mainObjectFileID: 2100000");
                metaContent.AppendLine("  userData:");
                metaContent.AppendLine("  assetBundleName:");
                metaContent.AppendLine("  assetBundleVariant:");
                File.WriteAllText(matFullPath + ".meta", metaContent.ToString());
            }
        }

        return material;
    }
}

posted @ 2024-10-23 16:28  请明月  阅读(4)  评论(0编辑  收藏  举报