主要作用就是减少ShaderLab的大小,如下图,大概能减少30M左右的内存。
直接上代码:
private static void ReplaceStandard()
{
dicReplaceMat = new Dictionary<string, List<string>>();
//替换所有fbx下material的shader
string type = "*.fbx";
List<string> resPath = new List<string>();
string searchPath = "Assets/";
string[] dirs = Directory.GetFiles(searchPath, type, SearchOption.AllDirectories);
for (int j = 0; j < dirs.Length; j++)
{
dirs[j] = dirs[j].Replace('\\', '/').Substring(dirs[j].IndexOf("Assets"));
resPath.Add(dirs[j]);
}
for (int i = 0; i < resPath.Count; i++)
{
EditorUtility.DisplayProgressBar("修改FBX中的Material", i + "/" + resPath.Count, i * 1.0f / resPath.Count);
ReplaceStandardFBX(resPath[i]);
}
Debug.Log("resPath:" + resPath.Count);
PrintLog();
EditorUtility.ClearProgressBar();
}
private static void ReplaceStandardFBX(string path)
{
ModelImporter standardImporter = AssetImporter.GetAtPath(path) as ModelImporter;
GameObject standardObj = AssetDatabase.LoadAssetAtPath<GameObject>(path);
bool needReImport = false;
standardImporter.importMaterials = true;
standardImporter.materialLocation = ModelImporterMaterialLocation.External;
Renderer[] skins = standardObj.GetComponentsInChildren<Renderer>(true);
Material noneMat = AssetDatabase.LoadAssetAtPath<Material>("Assets/Effect/SQMat/SQMat.mat");
for (int i = 0; i < skins.Length; i++)
{
Renderer renderer = skins[i];
if (renderer.sharedMaterials != null && renderer.sharedMaterials.Length > 0)
{
for (int j = 0; j < renderer.sharedMaterials.Length; j++)
{
Material mat = renderer.sharedMaterials[j];
if (mat != null && mat.shader.name == "Standard")
{
List<string> lstInfo = new List<string>();
if (dicReplaceMat.ContainsKey(path))
{
lstInfo = dicReplaceMat[path];
}
else
{
dicReplaceMat.Add(path, lstInfo);
}
if (noneMat)
{
standardImporter.materialLocation = ModelImporterMaterialLocation.External;
needReImport = true;
renderer.sharedMaterials[j] = noneMat;
lstInfo.Add(renderer.sharedMaterials[j].name);
}
}
}
}
}
if (!needReImport && standardImporter.materialLocation == ModelImporterMaterialLocation.External)
{
standardImporter.materialLocation = ModelImporterMaterialLocation.InPrefab;
}
standardImporter.SaveAndReimport();
AssetDatabase.Refresh();
standardImporter.materialLocation = ModelImporterMaterialLocation.InPrefab;
bool hasChanged = false;
if (standardImporter && standardImporter.importMaterials)
{
Dictionary<AssetImporter.SourceAssetIdentifier, UnityEngine.Object> dic = standardImporter.GetExternalObjectMap();
foreach (AssetImporter.SourceAssetIdentifier identifier in dic.Keys)
{
UnityEngine.Object obj = dic[identifier];
if (obj is Material)
{
Material material = (Material)obj;
if(material.shader.name == "Standard")
{
//去除原调用
standardImporter.RemoveRemap(identifier);
//替换新引用
standardImporter.AddRemap(identifier, noneMat);
hasChanged = true;
}
}
}
}
if (hasChanged)
{
//替换模式才能重导
standardImporter.SaveAndReimport();
}
}