using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.EditorCoroutines.Editor;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Assets.Snowstorm.Editor
{
class CheckOrChangeUnityShader : EditorWindow
{
public enum MatType
{
Standard = 0,
ParticleSystem = 1,
Sprite = 2,
Normal = 3,
}
static CheckOrChangeUnityShader self;
static Material replacedStandardMat;
static Material replacedSpriteMat;
static Material replacedParticleSystemMat;
static Dictionary<MatType, Material> typeAndMaterial;
static List<Shader> shadersInProject;
static List<Material> matsInProject;
static Dictionary<string, Shader> shaderNameAndShaders;
static Dictionary<string, List<Material>> shaderNameAndMats;
static Dictionary<string, List<Material>> wrongShaderNameAndMats;
static List<string> NotFoundShaderList;
static List<Material> sameNameMat;
static List<Material> noEnvenSameNameMat;
static List<Material> standardMat;
public static void InitReplacedMats()
{
replacedStandardMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_Mat.mat")[0] as Material;
replacedSpriteMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_Sprite.mat")[0] as Material;
replacedParticleSystemMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_ParticleSystem.mat")[0] as Material;
typeAndMaterial = new Dictionary<MatType, Material>();
typeAndMaterial.Add(MatType.ParticleSystem, replacedParticleSystemMat);
typeAndMaterial.Add(MatType.Sprite, replacedSpriteMat);
typeAndMaterial.Add(MatType.Standard, replacedStandardMat);
typeAndMaterial.Add(MatType.Normal, replacedStandardMat);
wrongShaderNameAndMats = new Dictionary<string, List<Material>>();
shadersInProject = new List<Shader>();
shaderNameAndShaders = new Dictionary<string, Shader>();
matsInProject = new List<Material>();
shaderNameAndMats = new Dictionary<string, List<Material>>();
NotFoundShaderList = new List<string>();
sameNameMat = new List<Material>();
noEnvenSameNameMat = new List<Material>();
standardMat = new List<Material>();
}
public static MatType GetReplacedMatType(Material srcMat)
{
if (srcMat == null)
{
return MatType.Standard;
}
else if (srcMat.name.Equals("Default-ParticleSystem")
|| srcMat..Equals("Particles/Standard Unlit"))
{
return MatType.ParticleSystem;
}
else if (srcMat.name.Equals("Sprites-Default")
|| srcMat..Equals("Sprites/Default"))
{
return MatType.Sprite;
}
else if (srcMat.name.Equals("Default-Material")
|| srcMat..Equals("Standard"))
{
return MatType.Standard;
}
return MatType.Normal;
}
[MenuItem("Tools/Shader/OptimizeShaders")]
public static CheckOrChangeUnityShader GetWindow()
{
if (self == null)
self = GetWindow<CheckOrChangeUnityShader>();
self.Show();
return self;
}
private void OnGUI()
{
GUILayout.Label("OptimizeShaders");
if (GUILayout.Button("Check And Optimize Shaders"))
{
InitReplacedMats();
CheckAndFixAllFbxStandardMat();
if(OptimizeMat())
{
ChangeSceneObjDefaultMat();
FixPrefabStandardShader();
ClearShaderData();
ExportShaderVariantAndSplit();
}
else
{
GUILayout.Button("There is an error, please look at: " + Application.dataPath + "/AllProjectShaders.txt");
}
}
}
#region fbx
public static IEnumerator ChangeModelMatExternal(string[] materialGUIDArray)
{
GameObject obj = null;
string path = "";
for (int i = 0; i < materialGUIDArray.Length; i++)
{
path = AssetDatabase.GUIDToAssetPath(materialGUIDArray[i]);
obj = AssetDatabase.LoadAllAssetsAtPath(path)[0] as GameObject;
if (null != obj)
{
string assetPath = AssetDatabase.GetAssetPath(obj);
ModelImporter importer = AssetImporter.GetAtPath(assetPath) as ModelImporter;
if (!(null == importer || (importer.importMaterials && importer.materialLocation == ModelImporterMaterialLocation.External)))
{
Debug.Log(assetPath);
importer.importMaterials = true;
importer.materialLocation = ModelImporterMaterialLocation.External;
importer.materialName = ModelImporterMaterialName.BasedOnModelNameAndMaterialName;
importer.materialSearch = ModelImporterMaterialSearch.Local;
importer.SaveAndReimport();
}
}
}
yield return null;
}
static void CheckAndFixAllFbxStandardMat()
{
string[] materialGUIDArray = AssetDatabase.FindAssets("t:model", new string[1] { "Assets" });
if (materialGUIDArray == null && materialGUIDArray.Length == 0)
{
return;
}
EditorCoroutineUtility.StartCoroutineOwnerless(ChangeModelMatExternal(materialGUIDArray));
}
#endregion
#region material operation
static void findAllShadersInProject()
{
string[] shaderGUIDArray = AssetDatabase.FindAssets("t:shader", new string[1] { "Assets" });
shadersInProject.Clear();
shaderNameAndShaders.Clear();
Shader shader = null;
string path = "";
for (int i = 0; i < shaderGUIDArray.Length; i++)
{
path = AssetDatabase.GUIDToAssetPath(shaderGUIDArray[i]);
shader = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Shader;
if (shader)
{
shadersInProject.Add(shader);
shaderNameAndShaders.Add(, shader);
EditorUtility.DisplayProgressBar("findAllShadersInProject", "Shader -> " + , i / shaderGUIDArray.Length);
}
}
}
static void findAllMatsInProject()
{
string[] materialGUIDArray = AssetDatabase.FindAssets("t:material", new string[1] { "Assets" });
matsInProject.Clear();
Material mat = null;
string path = "";
for (int i = 0; i < materialGUIDArray.Length; i++)
{
path = AssetDatabase.GUIDToAssetPath(materialGUIDArray[i]);
mat = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Material;
if (mat)
{
matsInProject.Add(mat);
EditorUtility.DisplayProgressBar("findAllMatsInProject", "Material -> " + mat.name, i / materialGUIDArray.Length);
}
}
}
[MenuItem("Assets/Shader/AllShaderAndMatInfos")]
static bool findAllShaderAndItsMat()
{
InitReplacedMats();
if (shadersInProject == null || shadersInProject.Count == 0)
{
findAllShadersInProject();
}
if (matsInProject == null || matsInProject.Count == 0)
{
findAllMatsInProject();
}
for (int i = 0; i < matsInProject.Count; i++)
{
EditorUtility.DisplayProgressBar("Check material and its shader", "Material -> " + matsInProject[i].name, i / matsInProject.Count);
// 对应的shader不在工程内
if (!shadersInProject.Contains(matsInProject[i].shader))
{
//所有shader不存在的、对应不上的,有问题的列表 shader和材质列表进行搜集
if (wrongShaderNameAndMats.ContainsKey(matsInProject[i].))
{
wrongShaderNameAndMats[matsInProject[i].].Add(matsInProject[i]);
}
else
{
List<Material> matList = new List<Material>();
matList.Add(matsInProject[i]);
wrongShaderNameAndMats.Add(matsInProject[i]., matList);
}
//shader不存在,但存在同名的shader
if (shaderNameAndShaders.ContainsKey(matsInProject[i].))
{
sameNameMat.Add(matsInProject[i]);
}
else
{
//同名的都不存在
if (!matsInProject[i]..Equals("Standard"))
{
noEnvenSameNameMat.Add(matsInProject[i]);
NotFoundShaderList.Add(matsInProject[i].name);
}
else
{
standardMat.Add(matsInProject[i]);
}
}
}
else
{
if (shaderNameAndMats.ContainsKey(matsInProject[i].))
{
shaderNameAndMats[matsInProject[i].].Add(matsInProject[i]);
}
else
{
List<Material> matList = new List<Material>();
matList.Add(matsInProject[i]);
shaderNameAndMats.Add(matsInProject[i]., matList);
}
}
}
EditorUtility.ClearProgressBar();
//写文件 文件名为save.text
//这里的FileMode.create是创建这个文件,如果文件名存在则覆盖重新创建
FileStream fs = new FileStream(Application.dataPath + "/AllProjectShaders.txt", FileMode.Create);
byte[] bytesTile = new UTF8Encoding().GetBytes("所有有问题的,shader有同名但对不上的和连同名都没有的: " + "\r\n");
fs.Write(bytesTile, 0, bytesTile.Length);
foreach (KeyValuePair<string, List<Material>> shaderAndMat in wrongShaderNameAndMats)
{
byte[] bytes = new UTF8Encoding().GetBytes(shaderAndMat.Key + "\r\n");
fs.Write(bytes, 0, bytes.Length);
foreach (var item in shaderAndMat.Value)
{
byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
fs.Write(bytes1, 0, bytes1.Length);
}
byte[] bytes2 = new UTF8Encoding().GetBytes("\r\n" + "\r\n");
fs.Write(bytes2, 0, bytes2.Length);
}
bytesTile = new UTF8Encoding().GetBytes("Same Name Material,所有有同名的 " + "\r\n");
fs.Write(bytesTile, 0, bytesTile.Length);
foreach (var item in sameNameMat)
{
byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
fs.Write(bytes1, 0, bytes1.Length);
}
bytesTile = new UTF8Encoding().GetBytes("Not Exist even Same Name Material,连同名的都没有的 " + "\r\n");
fs.Write(bytesTile, 0, bytesTile.Length);
foreach (var item in noEnvenSameNameMat)
{
byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
fs.Write(bytes1, 0, bytes1.Length);
}
bytesTile = new UTF8Encoding().GetBytes("Standard Material,用的标准shader的 " + "\r\n");
fs.Write(bytesTile, 0, bytesTile.Length);
foreach (var item in standardMat)
{
byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
fs.Write(bytes1, 0, bytes1.Length);
}
//每次读取文件后都要记得关闭文件
fs.Close();
if (noEnvenSameNameMat.Count > 0)
{
return false;
}
return true;
}
// 刷所有材质上的标准shader、指认shader
[MenuItem("Assets/Shader/OptimizeMat")]
static bool OptimizeMat()
{
if (!findAllShaderAndItsMat())
{
return false;
}
else
{
for (int i = 0; i < standardMat.Count; i++)
{
standardMat[i].shader = Shader.Find("Mobile/Diffuse");
}
for (int i = 0; i < sameNameMat.Count; i++)
{
standardMat[i].shader = shaderNameAndShaders[standardMat[i].];
}
Debug.Log("Optimize material and shader Success!");
return true;
}
}
#endregion material operation
static void ClearShaderData()
{
shadersInProject = null;
matsInProject = null;
shaderNameAndShaders = null;
shaderNameAndMats = null;
wrongShaderNameAndMats = null;
sameNameMat = null;
noEnvenSameNameMat = null;
standardMat = null;
NotFoundShaderList = null;
}
//每个物体的检查和替换代码封装
private static bool CheckAndReplaceObjectMats(ref GameObject obj)
{
MatType type = MatType.Normal;
Renderer[] allRender = obj.GetComponentsInChildren<Renderer>(true);
ParticleSystemRenderer[] allParticleSystemRenderers = obj.GetComponentsInChildren<ParticleSystemRenderer>(true);
bool needSave = false;
for (int j = 0; j < allRender.Length; j++)
{
Material[] srcMats = allRender[j].sharedMaterials;
bool needSaveMats = false;
if (srcMats != null)
{
for (int k = 0; k < srcMats.Length; k++)
{
type = MatType.Normal;
if (GetReplacedMatType(srcMats[k]) != MatType.Normal)
{
needSaveMats = true;
needSave = true;
srcMats[k] = typeAndMaterial[type];
}
}
if (needSaveMats)
{
allRender[j].sharedMaterials = srcMats;
}
}
}
for (int j = 0; j < allParticleSystemRenderers.Length; j++)
{
Material[] srcMats = allParticleSystemRenderers[j].sharedMaterials;
if (srcMats != null)
{
bool needSaveMats = false;
for (int k = 0; k < srcMats.Length; k++)
{
type = MatType.Normal;
if (GetReplacedMatType(srcMats[k]) != MatType.Normal)
{
needSaveMats = true;
needSave = true;
srcMats[k] = typeAndMaterial[type];
}
}
if (needSaveMats)
{
allParticleSystemRenderers[j].sharedMaterials = srcMats;
}
}
Material trailMat = allParticleSystemRenderers[j].trailMaterial;
type = MatType.Normal;
if (GetReplacedMatType(trailMat) != MatType.Normal)
{
needSave = true;
allParticleSystemRenderers[j].trailMaterial = typeAndMaterial[type];
}
}
return needSave;
}
#region SceneObject
//所有场景中的所有物体中的内置的几种材质shader替换掉
static void ChangeSceneObjDefaultMat()
{
string headPath = Application.dataPath;
//eg:D:/Project/Test/
headPath = headPath.Substring(0, headPath.IndexOf("Assets"));
List<string> optimizedOriginalScenePaths = new List<string>();
TextureModifier.AddRootSourcePathToList("Assets/Snowstorm", headPath, "Scene", ref optimizedOriginalScenePaths); ///Env/Scenes
for (int i = 0; i < optimizedOriginalScenePaths.Count; i++)
{
EditorUtility.DisplayProgressBar("ChangeSceneObjDefaultMat", "Scene -> " + optimizedOriginalScenePaths[i], i / optimizedOriginalScenePaths.Count);
EditorSceneManager.OpenScene(optimizedOriginalScenePaths[i], OpenSceneMode.Single);
GameObject[] gameObject = UnityEngine.Object.FindObjectsOfType<GameObject>();
bool needSave = false;
for (int k = 0; k < gameObject.Length; k++)
{
needSave = CheckAndReplaceObjectMats(ref gameObject[k]);
}
if (needSave)
{
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
}
}
EditorUtility.ClearProgressBar();
}
#endregion
#region prefabFix
// 所有prefab检查修改
[MenuItem("Assets/Shader/FixPrefabStandardShader")]
static void FixPrefabStandardShader()
{
InitReplacedMats();
Scene newScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand;
Dictionary<string, bool> wrongStandardPrefabList = new Dictionary<string, bool>();
Dictionary<string, bool> wrongSpritePrefabList = new Dictionary<string, bool>();
Dictionary<string, bool> wrongParticleSystemPrefabList = new Dictionary<string, bool>();
Dictionary<MatType, Dictionary<string, bool>> wrongPrefabList = new Dictionary<MatType, Dictionary<string, bool>>();
wrongPrefabList.Add(MatType.ParticleSystem, wrongParticleSystemPrefabList);
wrongPrefabList.Add(MatType.Sprite, wrongSpritePrefabList);
wrongPrefabList.Add(MatType.Standard, wrongStandardPrefabList);
bool needSave = false;
List<Material> ms = new List<Material>();
GameObject prefabObj = null;
string[] prefabGUIDArray = AssetDatabase.FindAssets("t:prefab", new string[1] { "Assets" });
for (int i = 0; i < prefabGUIDArray.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(prefabGUIDArray[i]);
var asset = AssetDatabase.LoadAssetAtPath<GameObject>(path);
if (asset == null)
{
continue;
}
prefabObj = PrefabUtility.InstantiatePrefab(asset, SceneManager.GetActiveScene()) as GameObject;
EditorUtility.DisplayProgressBar("FixPrefabStandardShader", "Prefab -> " + prefabObj.name, i / prefabGUIDArray.Length);
needSave = CheckAndReplaceObjectMats(ref prefabObj);
if (needSave)
{
PrefabUtility.SaveAsPrefabAsset(prefabObj, path);
}
}
EditorUtility.ClearProgressBar();
Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
}
#endregion
//#region checkAgain
//static void CheckAgain()
//{
// var dict = new Dictionary<string, bool>();
// foreach (var assetBundleName in AssetDatabase.GetAllAssetBundleNames())
// {
// string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
// foreach (var dependency in AssetDatabase.GetDependencies(assetPaths, true))
// {
// if (!dict.ContainsKey(dependency))
// {
// Debug.Log(dependency + " 111111111 " + assetPaths);
// dict.Add(dependency, true);
// }
// }
// }
// var di = new DirectoryInfo("Assets");
// foreach (var fi in di.GetFiles("*", SearchOption.AllDirectories))
// {
// if (fi.Extension == ".meta")
// {
// continue;
// }
// string assetPath = fi.FullName.Replace(Application.dataPath, "Assets");
// foreach (var dependency in AssetDatabase.GetDependencies(assetPath, true))
// {
// if (!dict.ContainsKey(dependency))
// {
// Debug.Log(dependency + " 2222222222 " + assetPath);
// dict.Add(dependency, true);
// }
// }
// }
// string[] scenes = (from scene in EditorBuildSettings.scenes
// where scene.enabled
// select scene.path).ToArray();
// foreach (var dependency in AssetDatabase.GetDependencies(scenes, true))
// {
// if (!dict.ContainsKey(dependency))
// {
// Debug.Log(dependency + " 33333333333 ");
// dict.Add(dependency, true);
// }
// }
// var materials = new List<Material>();
// var shaderDict = new Dictionary<Shader, List<Material>>();
// foreach (var assetPath in dict.Keys)
// {
// var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
// if (material != null)
// {
// if (material.shader != null)
// {
// if (shadersInProject.Contains(material.shader))
// {
// continue;
// }
// else
// {
// if(!noEnvenSameNameMat.Contains(material))
// {
// noEnvenSameNameMat.Add(material);
// NotFoundShaderList.Add(material.name);
// }
// }
// }
// }
// }
// FileStream fs = new FileStream(Application.dataPath + "/NotFoundShader.txt", FileMode.Create);
// //存储时时二进制,所以这里需要把我们的字符串转成二进制
// byte[] bytesElement = new UTF8Encoding().GetBytes("没找到的shader: " + "\r\n");
// fs.Write(bytesElement, 0, bytesElement.Length);
// foreach (var item in NotFoundShaderList)
// {
// byte[] bytes = new UTF8Encoding().GetBytes(item + "\r\n");
// fs.Write(bytes, 0, bytes.Length);
// }
// bytesElement = new UTF8Encoding().GetBytes("没找到shader的材质: " + "\r\n");
// fs.Write(bytesElement, 0, bytesElement.Length);
// foreach (var item in noEnvenSameNameMat)
// {
// byte[] bytes = new UTF8Encoding().GetBytes(item + "\r\n");
// fs.Write(bytes, 0, bytes.Length);
// }
// byte[] bytesEnd = new UTF8Encoding().GetBytes("\r\n");
// fs.Write(bytesEnd, 0, bytesEnd.Length);
//}
//#endregion
#region ExportAndSplit
static void ExportShaderVariantAndSplit()
{
Debug.Log("ExportShaderVariantAndSplit +++ ------------");
ShaderVariantCollectionExporter.Export();
ShaderVariantCollection svc = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Shader/SVC_T.shadervariants")[0] as ShaderVariantCollection;
if (Directory.Exists(Application.dataPath + "/Snowstorm/Shader/ShaderVariantBank"))
{
Directory.Delete(Application.dataPath + "/Snowstorm/Shader/ShaderVariantBank", true);
Debug.Log("删除shaderVariantBank文件夹");
}
if (!Directory.Exists(Application.dataPath + "/Snowstorm/Shader/ShaderVariants"))
{
Directory.CreateDirectory(Application.dataPath + "/Snowstorm/Shader/ShaderVariants");
Debug.Log("删除shaderVariants文件夹");
}
SplitShaderVariantsCollectionEditor.SplitShaderVariantCollection(svc);
Debug.Log("All Succeed, please look at txt !!");
}
#endregion
}
}输出shader变体
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using Debug = UnityEngine.Debug;
using System.Text;
[InitializeOnLoad]
public static class ShaderVariantCollectionExporter
{
private static bool _isStarted;
private static readonly Stopwatch _elapsedTime = new Stopwatch();
private const string ShaderVariantCollectionPath = "Assets/Snowstorm/Shader/SVC_T.shadervariants";
private const int WaitTimeBeforeSave = 1000;
private const string CollectionDirectoryPath = "Assets";
[MenuItem("Tools/Shader/Export ShaderVariantCollection")]
public static void Export()
{
var dict = new Dictionary<string, bool>();
foreach (var assetBundleName in AssetDatabase.GetAllAssetBundleNames())
{
string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
foreach (var dependency in AssetDatabase.GetDependencies(assetPaths, true))
{
if (!dict.ContainsKey(dependency))
{
Debug.Log(dependency + " 111111111 " + assetPaths);
dict.Add(dependency, true);
}
}
}
var di = new DirectoryInfo(CollectionDirectoryPath);
foreach (var fi in di.GetFiles("*", SearchOption.AllDirectories))
{
if (fi.Extension == ".meta")
{
continue;
}
string assetPath = fi.FullName.Replace(Application.dataPath, "Assets");
foreach (var dependency in AssetDatabase.GetDependencies(assetPath, true))
{
if (!dict.ContainsKey(dependency))
{
Debug.Log(dependency + " 2222222222 " + assetPath);
dict.Add(dependency, true);
}
}
}
string[] scenes = (from scene in EditorBuildSettings.scenes
where scene.enabled
select scene.path).ToArray();
foreach (var dependency in AssetDatabase.GetDependencies(scenes, true))
{
if (!dict.ContainsKey(dependency))
{
Debug.Log(dependency + " 33333333333 " );
dict.Add(dependency, true);
}
}
var materials = new List<Material>();
var shaderDict = new Dictionary<Shader, List<Material>>();
foreach (var assetPath in dict.Keys)
{
var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
if (material != null)
{
if (material.shader != null)
{
if (!shaderDict.ContainsKey(material.shader))
{
shaderDict.Add(material.shader, new List<Material>());
}
if (!shaderDict[material.shader].Contains(material))
{
shaderDict[material.shader].Add(material);
}
}
if (!materials.Contains(material))
{
materials.Add(material);
}
}
}
List<Shader> shadersInProject = new List<Shader>();
string[] shaderGUIDArray = AssetDatabase.FindAssets("t:shader", new string[1] { "Assets" });
Shader shader = null;
string path = "";
for (int i = 0; i < shaderGUIDArray.Length; i++)
{
path = AssetDatabase.GUIDToAssetPath(shaderGUIDArray[i]);
shader = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Shader;
if (shader)
{
shadersInProject.Add(shader);
EditorUtility.DisplayProgressBar("ShaderVariantCollectionExporter findAllShadersInProject", "Shader -> " + , i / shaderGUIDArray.Length);
}
}
EditorUtility.ClearProgressBar();
Dictionary<Shader, List<Material>> notProjectShader = new Dictionary<Shader, List<Material>>();
foreach(KeyValuePair<Shader, List<Material>> item in shaderDict)
{
if(!shadersInProject.Contains(item.Key))
{
notProjectShader.Add(item.Key, item.Value);
}
}
FileStream fs = new FileStream(Application.dataPath + "/DependencyShader.txt", FileMode.Create);
//存储时时二进制,所以这里需要把我们的字符串转成二进制
foreach (KeyValuePair<Shader, List<Material>> item in shaderDict)
{
byte[] bytes = new UTF8Encoding().GetBytes(item.Key + "\r\n");
fs.Write(bytes, 0, bytes.Length);
foreach (var mat in item.Value)
{
byte[] bytesElement = new UTF8Encoding().GetBytes(AssetDatabase.GetAssetPath(mat) + "\r\n");
fs.Write(bytesElement, 0, bytesElement.Length);
}
byte[] bytesEnd = new UTF8Encoding().GetBytes("\r\n");
fs.Write(bytesEnd, 0, bytesEnd.Length);
}
byte[] bytesTitle = new UTF8Encoding().GetBytes("not in project shaders \r\n");
fs.Write(bytesTitle, 0, bytesTitle.Length);
foreach (KeyValuePair<Shader, List<Material>> item in notProjectShader)
{
byte[] bytes = new UTF8Encoding().GetBytes(item.Key + "\r\n");
fs.Write(bytes, 0, bytes.Length);
foreach (var mat in item.Value)
{
byte[] bytesElement = new UTF8Encoding().GetBytes(AssetDatabase.GetAssetPath(mat) + "\r\n");
fs.Write(bytesElement, 0, bytesElement.Length);
}
byte[] bytesEnd = new UTF8Encoding().GetBytes("\r\n");
fs.Write(bytesEnd, 0, bytesEnd.Length);
}
//每次读取文件后都要记得关闭文件
fs.Close();
fs = null;
ProcessMaterials(materials);
var sb = new System.Text.StringBuilder();
foreach (var kvp in shaderDict)
{
sb.AppendLine(kvp.Key + " " + kvp.Value.Count + " times");
if (kvp.Value.Count <= 5)
{
Debug.LogWarning("Shader: " + kvp.Key.name, kvp.Key);
foreach (var m in kvp.Value)
{
Debug.Log(AssetDatabase.GetAssetPath(m), m);
}
}
}
Debug.Log(sb.ToString());
}
static ShaderVariantCollectionExporter()
{
EditorApplication.update += EditorUpdate;
}
private static void EditorUpdate()
{
if (_isStarted && _elapsedTime.ElapsedMilliseconds >= WaitTimeBeforeSave)
{
Debug.Log(InvokeInternalStaticMethod(typeof(ShaderUtil),
"GetCurrentShaderVariantCollectionVariantCount"));
_elapsedTime.Stop();
_elapsedTime.Reset();
_isStarted = false;
EditorApplication.isPlaying = false;
InvokeInternalStaticMethod(typeof(ShaderUtil), "SaveCurrentShaderVariantCollection",
ShaderVariantCollectionPath);
Debug.Log(
InvokeInternalStaticMethod(typeof(ShaderUtil), "GetCurrentShaderVariantCollectionShaderCount"));
}
}
private static void ProcessMaterials(List<Material> materials)
{
EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);
InvokeInternalStaticMethod(typeof(ShaderUtil), "ClearCurrentShaderVariantCollection");
Debug.Log(InvokeInternalStaticMethod(typeof(ShaderUtil), "GetCurrentShaderVariantCollectionShaderCount"));
int totalMaterials = materials.Count;
var camera = Camera.main;
if (camera == null)
{
Debug.LogError("Main Camera didn't exist");
return;
}
float aspect = camera.aspect;
float height = Mathf.Sqrt(totalMaterials / aspect) + 1;
float width = Mathf.Sqrt(totalMaterials / aspect) * aspect + 1;
float halfHeight = Mathf.CeilToInt(height / 2f);
float halfWidth = Mathf.CeilToInt(width / 2f);
camera.orthographic = true;
camera.orthographicSize = halfHeight;
camera.transform.position = new Vector3(0f, 0f, -10f);
Selection.activeGameObject = camera.gameObject;
EditorApplication.ExecuteMenuItem("GameObject/Align View to Selected");
int xMax = (int) (width - 1);
int x = 0;
int y = 0;
for (int i = 0; i < materials.Count; i++)
{
var material = materials[i];
var position = new Vector3(x - halfWidth + 1f, y - halfHeight + 1f, 0f);
CreateSphere(material, position, x, y, i);
if (x == xMax)
{
x = 0;
y++;
}
else
{
x++;
}
}
_elapsedTime.Stop();
_elapsedTime.Reset();
_elapsedTime.Start();
_isStarted = true;
}
private static void CreateSphere(Material material, Vector3 position, int x, int y, int index)
{
var go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
go.GetComponent<Renderer>().material = material;
go.transform.position = position;
= string.Format("Sphere_{0}|{1}_{2}|{3}", index, x, y, material.name);
}
private static object InvokeInternalStaticMethod(System.Type type, string method, params object[] parameters)
{
var methodInfo = type.GetMethod(method, BindingFlags.NonPublic | BindingFlags.Static);
if (methodInfo == null)
{
Debug.LogError(string.Format("{0} method didn't exist", method));
return null;
}
return methodInfo.Invoke(null, parameters);
}
}Split shader变体
using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
public class SplitShaderVariantsCollectionEditor : EditorWindow
{
static SplitShaderVariantsCollectionEditor _self;
private ShaderVariantCollection _svc;
private static string _shaderVariantBankFolder = "Assets/Snowstorm/Shader/ShaderVariantBank";
[MenuItem("Tools/Shader/SplitShaderVariantsCollectionEditor")]
public static SplitShaderVariantsCollectionEditor GetWindow()
{
if (_self == null)
_self = GetWindow<SplitShaderVariantsCollectionEditor>();
_self.Show();
return _self;
}
private void OnGUI()
{
GUILayout.Label("Split ShaderVariantCollection");
var tempSVC =
EditorGUILayout.ObjectField(_svc, typeof(ShaderVariantCollection), false) as ShaderVariantCollection;
if (tempSVC != _svc)
{
_svc = tempSVC;
}
if (_svc != null)
{
if (GUILayout.Button("Split SVC"))
{
SplitShaderVariantCollection(_svc);
}
}
}
public static void SplitShaderVariantCollection(ShaderVariantCollection svc)
{
try
{
string outPath =
Path.Combine(Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("/Assets")),
_shaderVariantBankFolder);
if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath);
var svcPath = Path.Combine(Path.GetDirectoryName(AssetDatabase.GetAssetPath(svc)),
"ShaderVariants");
if (!Directory.Exists(svcPath)) Directory.CreateDirectory(svcPath);
var serializedObject = new SerializedObject(svc);
var m_Shaders = serializedObject.FindProperty("m_Shaders");
ShaderVariantBank shaderVariantBank = ScriptableObject.CreateInstance<ShaderVariantBank>();
if (m_Shaders != null)
{
StringBuilder sb = new StringBuilder();
for (var i = 0; i < m_Shaders.arraySize; ++i)
{
var entryProp = m_Shaders.GetArrayElementAtIndex(i);
var shader = (Shader) entryProp.FindPropertyRelative("first").objectReferenceValue;
if (shader != null)
{
EditorUtility.DisplayProgressBar("Spliting SVC", "Shader -> " + ,
(i + 1) * 1.0f / m_Shaders.arraySize);
// Variants for this shader
var variantsProp = entryProp.FindPropertyRelative("second.variants");
for (var j = 0; j < variantsProp.arraySize; ++j)
{
sb.Clear();
var newSVC = new ShaderVariantCollection();
var prop = variantsProp.GetArrayElementAtIndex(j);
var keywords = prop.FindPropertyRelative("keywords").stringValue;
string[] keywordsArr = null;
if (!string.IsNullOrEmpty(keywords))
{
keywordsArr = keywords.Split(' ');
}
var passType =
(UnityEngine.Rendering.PassType) prop.FindPropertyRelative("passType").intValue;
newSVC.Add(new ShaderVariantCollection.ShaderVariant(shader, passType, keywordsArr));
var path = Path.Combine(Path.GetDirectoryName(AssetDatabase.GetAssetPath(svc)),
"ShaderVariants");
var filename = sb.Append(.Replace('/', '_').Replace(' ', '_')).Append("_").Append(keywords)
.Append(".shadervariants");
shaderVariantBank.AddShaderVariantName(Path.Combine("Shader/ShaderVariants", filename.ToString()));
//shaderVariantBank.AddShaderVariantCollection(newSVC);
Debug.Log(string.Format("{0}_{1}", , keywords));
var output = Path.Combine(path, filename.ToString());
AssetDatabase.CreateAsset(newSVC, output);
}
}
else
{
Debug.LogWarning("has missing shader.");
}
}
AssetDatabase.Refresh();
AssetDatabase.CreateAsset(shaderVariantBank,
Path.Combine(_shaderVariantBankFolder, "ShaderVariantBank") + ".asset");
EditorUtility.ClearProgressBar();
}
}
catch (Exception e)
{
EditorUtility.DisplayDialog("错误", e.ToString(), "确定");
EditorUtility.ClearProgressBar();
throw;
}
}
}CheckOrChangeUnityShader.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.EditorCoroutines.Editor;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Assets.Snowstorm.Editor
{
class CheckOrChangeUnityShader : EditorWindow
{
public enum MatType
{
Standard = 0,
ParticleSystem = 1,
Sprite = 2,
Normal = 3,
}
static CheckOrChangeUnityShader self;
static Material replacedStandardMat;
static Material replacedSpriteMat;
static Material replacedParticleSystemMat;
static Dictionary<MatType, Material> typeAndMaterial;
static List<Shader> shadersInProject;
static List<Material> matsInProject;
static Dictionary<string, Shader> shaderNameAndShaders;
static Dictionary<string, List<Material>> shaderNameAndMats;
static Dictionary<string, List<Material>> wrongShaderNameAndMats;
static List<string> NotFoundShaderList;
static List<Material> sameNameMat;
static List<Material> noEnvenSameNameMat;
static List<Material> standardMat;
public static void InitReplacedMats()
{
replacedStandardMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_Mat.mat")[0] as Material;
replacedSpriteMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_Sprite.mat")[0] as Material;
replacedParticleSystemMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_ParticleSystem.mat")[0] as Material;
typeAndMaterial = new Dictionary<MatType, Material>();
typeAndMaterial.Add(MatType.ParticleSystem, replacedParticleSystemMat);
typeAndMaterial.Add(MatType.Sprite, replacedSpriteMat);
typeAndMaterial.Add(MatType.Standard, replacedStandardMat);
typeAndMaterial.Add(MatType.Normal, replacedStandardMat);
wrongShaderNameAndMats = new Dictionary<string, List<Material>>();
shadersInProject = new List<Shader>();
shaderNameAndShaders = new Dictionary<string, Shader>();
matsInProject = new List<Material>();
shaderNameAndMats = new Dictionary<string, List<Material>>();
NotFoundShaderList = new List<string>();
sameNameMat = new List<Material>();
noEnvenSameNameMat = new List<Material>();
standardMat = new List<Material>();
}
public static MatType GetReplacedMatType(Material srcMat)
{
if (srcMat == null)
{
return MatType.Standard;
}
else if (srcMat.name.Equals("Default-ParticleSystem")
|| srcMat..Equals("Particles/Standard Unlit"))
{
return MatType.ParticleSystem;
}
else if (srcMat.name.Equals("Sprites-Default")
|| srcMat..Equals("Sprites/Default"))
{
return MatType.Sprite;
}
else if (srcMat.name.Equals("Default-Material")
|| srcMat..Equals("Standard"))
{
return MatType.Standard;
}
return MatType.Normal;
}
[MenuItem("Tools/Shader/OptimizeShaders")]
public static CheckOrChangeUnityShader GetWindow()
{
if (self == null)
self = GetWindow<CheckOrChangeUnityShader>();
self.Show();
return self;
}
private void OnGUI()
{
GUILayout.Label("OptimizeShaders");
if (GUILayout.Button("Check And Optimize Shaders"))
{
InitReplacedMats();
CheckAndFixAllFbxStandardMat();
if(OptimizeMat())
{
ChangeSceneObjDefaultMat();
FixPrefabStandardShader();
ClearShaderData();
ExportShaderVariantAndSplit();
}
else
{
GUILayout.Button("There is an error, please look at: " + Application.dataPath + "/AllProjectShaders.txt");
}
}
}
#region fbx
public static IEnumerator ChangeModelMatExternal(string[] materialGUIDArray)
{
GameObject obj = null;
string path = "";
for (int i = 0; i < materialGUIDArray.Length; i++)
{
path = AssetDatabase.GUIDToAssetPath(materialGUIDArray[i]);
obj = AssetDatabase.LoadAllAssetsAtPath(path)[0] as GameObject;
if (null != obj)
{
string assetPath = AssetDatabase.GetAssetPath(obj);
ModelImporter importer = AssetImporter.GetAtPath(assetPath) as ModelImporter;
if (!(null == importer || (importer.importMaterials && importer.materialLocation == ModelImporterMaterialLocation.External)))
{
Debug.Log(assetPath);
importer.importMaterials = true;
importer.materialLocation = ModelImporterMaterialLocation.External;
importer.materialName = ModelImporterMaterialName.BasedOnModelNameAndMaterialName;
importer.materialSearch = ModelImporterMaterialSearch.Local;
importer.SaveAndReimport();
}
}
}
yield return null;
}
static void CheckAndFixAllFbxStandardMat()
{
string[] materialGUIDArray = AssetDatabase.FindAssets("t:model", new string[1] { "Assets" });
if (materialGUIDArray == null && materialGUIDArray.Length == 0)
{
return;
}
EditorCoroutineUtility.StartCoroutineOwnerless(ChangeModelMatExternal(materialGUIDArray));
}
#endregion
#region material operation
static void findAllShadersInProject()
{
string[] shaderGUIDArray = AssetDatabase.FindAssets("t:shader", new string[1] { "Assets" });
shadersInProject.Clear();
shaderNameAndShaders.Clear();
Shader shader = null;
string path = "";
for (int i = 0; i < shaderGUIDArray.Length; i++)
{
path = AssetDatabase.GUIDToAssetPath(shaderGUIDArray[i]);
shader = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Shader;
if (shader)
{
shadersInProject.Add(shader);
shaderNameAndShaders.Add(, shader);
EditorUtility.DisplayProgressBar("findAllShadersInProject", "Shader -> " + , i / shaderGUIDArray.Length);
}
}
}
static void findAllMatsInProject()
{
string[] materialGUIDArray = AssetDatabase.FindAssets("t:material", new string[1] { "Assets" });
matsInProject.Clear();
Material mat = null;
string path = "";
for (int i = 0; i < materialGUIDArray.Length; i++)
{
path = AssetDatabase.GUIDToAssetPath(materialGUIDArray[i]);
mat = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Material;
if (mat)
{
matsInProject.Add(mat);
EditorUtility.DisplayProgressBar("findAllMatsInProject", "Material -> " + mat.name, i / materialGUIDArray.Length);
}
}
}
[MenuItem("Assets/Shader/AllShaderAndMatInfos")]
static bool findAllShaderAndItsMat()
{
InitReplacedMats();
if (shadersInProject == null || shadersInProject.Count == 0)
{
findAllShadersInProject();
}
if (matsInProject == null || matsInProject.Count == 0)
{
findAllMatsInProject();
}
for (int i = 0; i < matsInProject.Count; i++)
{
EditorUtility.DisplayProgressBar("Check material and its shader", "Material -> " + matsInProject[i].name, i / matsInProject.Count);
// 对应的shader不在工程内
if (!shadersInProject.Contains(matsInProject[i].shader))
{
//所有shader不存在的、对应不上的,有问题的列表 shader和材质列表进行搜集
if (wrongShaderNameAndMats.ContainsKey(matsInProject[i].))
{
wrongShaderNameAndMats[matsInProject[i].].Add(matsInProject[i]);
}
else
{
List<Material> matList = new List<Material>();
matList.Add(matsInProject[i]);
wrongShaderNameAndMats.Add(matsInProject[i]., matList);
}
//shader不存在,但存在同名的shader
if (shaderNameAndShaders.ContainsKey(matsInProject[i].))
{
sameNameMat.Add(matsInProject[i]);
}
else
{
//同名的都不存在
if (!matsInProject[i]..Equals("Standard"))
{
noEnvenSameNameMat.Add(matsInProject[i]);
NotFoundShaderList.Add(matsInProject[i].name);
}
else
{
standardMat.Add(matsInProject[i]);
}
}
}
else
{
if (shaderNameAndMats.ContainsKey(matsInProject[i].))
{
shaderNameAndMats[matsInProject[i].].Add(matsInProject[i]);
}
else
{
List<Material> matList = new List<Material>();
matList.Add(matsInProject[i]);
shaderNameAndMats.Add(matsInProject[i]., matList);
}
}
}
EditorUtility.ClearProgressBar();
//写文件 文件名为save.text
//这里的FileMode.create是创建这个文件,如果文件名存在则覆盖重新创建
FileStream fs = new FileStream(Application.dataPath + "/AllProjectShaders.txt", FileMode.Create);
byte[] bytesTile = new UTF8Encoding().GetBytes("所有有问题的,shader有同名但对不上的和连同名都没有的: " + "\r\n");
fs.Write(bytesTile, 0, bytesTile.Length);
foreach (KeyValuePair<string, List<Material>> shaderAndMat in wrongShaderNameAndMats)
{
byte[] bytes = new UTF8Encoding().GetBytes(shaderAndMat.Key + "\r\n");
fs.Write(bytes, 0, bytes.Length);
foreach (var item in shaderAndMat.Value)
{
byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
fs.Write(bytes1, 0, bytes1.Length);
}
byte[] bytes2 = new UTF8Encoding().GetBytes("\r\n" + "\r\n");
fs.Write(bytes2, 0, bytes2.Length);
}
bytesTile = new UTF8Encoding().GetBytes("Same Name Material,所有有同名的 " + "\r\n");
fs.Write(bytesTile, 0, bytesTile.Length);
foreach (var item in sameNameMat)
{
byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
fs.Write(bytes1, 0, bytes1.Length);
}
bytesTile = new UTF8Encoding().GetBytes("Not Exist even Same Name Material,连同名的都没有的 " + "\r\n");
fs.Write(bytesTile, 0, bytesTile.Length);
foreach (var item in noEnvenSameNameMat)
{
byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
fs.Write(bytes1, 0, bytes1.Length);
}
bytesTile = new UTF8Encoding().GetBytes("Standard Material,用的标准shader的 " + "\r\n");
fs.Write(bytesTile, 0, bytesTile.Length);
foreach (var item in standardMat)
{
byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
fs.Write(bytes1, 0, bytes1.Length);
}
//每次读取文件后都要记得关闭文件
fs.Close();
if (noEnvenSameNameMat.Count > 0)
{
return false;
}
return true;
}
// 刷所有材质上的标准shader、指认shader
[MenuItem("Assets/Shader/OptimizeMat")]
static bool OptimizeMat()
{
if (!findAllShaderAndItsMat())
{
return false;
}
else
{
for (int i = 0; i < standardMat.Count; i++)
{
standardMat[i].shader = Shader.Find("Mobile/Diffuse");
}
for (int i = 0; i < sameNameMat.Count; i++)
{
standardMat[i].shader = shaderNameAndShaders[standardMat[i].];
}
Debug.Log("Optimize material and shader Success!");
return true;
}
}
#endregion material operation
static void ClearShaderData()
{
shadersInProject = null;
matsInProject = null;
shaderNameAndShaders = null;
shaderNameAndMats = null;
wrongShaderNameAndMats = null;
sameNameMat = null;
noEnvenSameNameMat = null;
standardMat = null;
NotFoundShaderList = null;
}
//每个物体的检查和替换代码封装
private static bool CheckAndReplaceObjectMats(ref GameObject obj)
{
MatType type = MatType.Normal;
Renderer[] allRender = obj.GetComponentsInChildren<Renderer>(true);
ParticleSystemRenderer[] allParticleSystemRenderers = obj.GetComponentsInChildren<ParticleSystemRenderer>(true);
bool needSave = false;
for (int j = 0; j < allRender.Length; j++)
{
Material[] srcMats = allRender[j].sharedMaterials;
bool needSaveMats = false;
if (srcMats != null)
{
for (int k = 0; k < srcMats.Length; k++)
{
type = MatType.Normal;
if (GetReplacedMatType(srcMats[k]) != MatType.Normal)
{
needSaveMats = true;
needSave = true;
srcMats[k] = typeAndMaterial[type];
}
}
if (needSaveMats)
{
allRender[j].sharedMaterials = srcMats;
}
}
}
for (int j = 0; j < allParticleSystemRenderers.Length; j++)
{
Material[] srcMats = allParticleSystemRenderers[j].sharedMaterials;
if (srcMats != null)
{
bool needSaveMats = false;
for (int k = 0; k < srcMats.Length; k++)
{
type = MatType.Normal;
if (GetReplacedMatType(srcMats[k]) != MatType.Normal)
{
needSaveMats = true;
needSave = true;
srcMats[k] = typeAndMaterial[type];
}
}
if (needSaveMats)
{
allParticleSystemRenderers[j].sharedMaterials = srcMats;
}
}
Material trailMat = allParticleSystemRenderers[j].trailMaterial;
type = MatType.Normal;
if (GetReplacedMatType(trailMat) != MatType.Normal)
{
needSave = true;
allParticleSystemRenderers[j].trailMaterial = typeAndMaterial[type];
}
}
return needSave;
}
#region SceneObject
//所有场景中的所有物体中的内置的几种材质shader替换掉
static void ChangeSceneObjDefaultMat()
{
string headPath = Application.dataPath;
//eg:D:/Project/Test/
headPath = headPath.Substring(0, headPath.IndexOf("Assets"));
List<string> optimizedOriginalScenePaths = new List<string>();
TextureModifier.AddRootSourcePathToList("Assets/Snowstorm", headPath, "Scene", ref optimizedOriginalScenePaths); ///Env/Scenes
for (int i = 0; i < optimizedOriginalScenePaths.Count; i++)
{
EditorUtility.DisplayProgressBar("ChangeSceneObjDefaultMat", "Scene -> " + optimizedOriginalScenePaths[i], i / optimizedOriginalScenePaths.Count);
EditorSceneManager.OpenScene(optimizedOriginalScenePaths[i], OpenSceneMode.Single);
GameObject[] gameObject = UnityEngine.Object.FindObjectsOfType<GameObject>();
bool needSave = false;
for (int k = 0; k < gameObject.Length; k++)
{
needSave = CheckAndReplaceObjectMats(ref gameObject[k]);
}
if (needSave)
{
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
}
}
EditorUtility.ClearProgressBar();
}
#endregion
#region prefabFix
// 所有prefab检查修改
[MenuItem("Assets/Shader/FixPrefabStandardShader")]
static void FixPrefabStandardShader()
{
InitReplacedMats();
Scene newScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand;
Dictionary<string, bool> wrongStandardPrefabList = new Dictionary<string, bool>();
Dictionary<string, bool> wrongSpritePrefabList = new Dictionary<string, bool>();
Dictionary<string, bool> wrongParticleSystemPrefabList = new Dictionary<string, bool>();
Dictionary<MatType, Dictionary<string, bool>> wrongPrefabList = new Dictionary<MatType, Dictionary<string, bool>>();
wrongPrefabList.Add(MatType.ParticleSystem, wrongParticleSystemPrefabList);
wrongPrefabList.Add(MatType.Sprite, wrongSpritePrefabList);
wrongPrefabList.Add(MatType.Standard, wrongStandardPrefabList);
bool needSave = false;
List<Material> ms = new List<Material>();
GameObject prefabObj = null;
string[] prefabGUIDArray = AssetDatabase.FindAssets("t:prefab", new string[1] { "Assets" });
for (int i = 0; i < prefabGUIDArray.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(prefabGUIDArray[i]);
var asset = AssetDatabase.LoadAssetAtPath<GameObject>(path);
if (asset == null)
{
continue;
}
prefabObj = PrefabUtility.InstantiatePrefab(asset, SceneManager.GetActiveScene()) as GameObject;
EditorUtility.DisplayProgressBar("FixPrefabStandardShader", "Prefab -> " + prefabObj.name, i / prefabGUIDArray.Length);
needSave = CheckAndReplaceObjectMats(ref prefabObj);
if (needSave)
{
PrefabUtility.SaveAsPrefabAsset(prefabObj, path);
}
}
EditorUtility.ClearProgressBar();
Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
}
#endregion
//#region checkAgain
//static void CheckAgain()
//{
// var dict = new Dictionary<string, bool>();
// foreach (var assetBundleName in AssetDatabase.GetAllAssetBundleNames())
// {
// string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
// foreach (var dependency in AssetDatabase.GetDependencies(assetPaths, true))
// {
// if (!dict.ContainsKey(dependency))
// {
// Debug.Log(dependency + " 111111111 " + assetPaths);
// dict.Add(dependency, true);
// }
// }
// }
// var di = new DirectoryInfo("Assets");
// foreach (var fi in di.GetFiles("*", SearchOption.AllDirectories))
// {
// if (fi.Extension == ".meta")
// {
// continue;
// }
// string assetPath = fi.FullName.Replace(Application.dataPath, "Assets");
// foreach (var dependency in AssetDatabase.GetDependencies(assetPath, true))
// {
// if (!dict.ContainsKey(dependency))
// {
// Debug.Log(dependency + " 2222222222 " + assetPath);
// dict.Add(dependency, true);
// }
// }
// }
// string[] scenes = (from scene in EditorBuildSettings.scenes
// where scene.enabled
// select scene.path).ToArray();
// foreach (var dependency in AssetDatabase.GetDependencies(scenes, true))
// {
// if (!dict.ContainsKey(dependency))
// {
// Debug.Log(dependency + " 33333333333 ");
// dict.Add(dependency, true);
// }
// }
// var materials = new List<Material>();
// var shaderDict = new Dictionary<Shader, List<Material>>();
// foreach (var assetPath in dict.Keys)
// {
// var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
// if (material != null)
// {
// if (material.shader != null)
// {
// if (shadersInProject.Contains(material.shader))
// {
// continue;
// }
// else
// {
// if(!noEnvenSameNameMat.Contains(material))
// {
// noEnvenSameNameMat.Add(material);
// NotFoundShaderList.Add(material.name);
// }
// }
// }
// }
// }
// FileStream fs = new FileStream(Application.dataPath + "/NotFoundShader.txt", FileMode.Create);
// //存储时时二进制,所以这里需要把我们的字符串转成二进制
// byte[] bytesElement = new UTF8Encoding().GetBytes("没找到的shader: " + "\r\n");
// fs.Write(bytesElement, 0, bytesElement.Length);
// foreach (var item in NotFoundShaderList)
// {
// byte[] bytes = new UTF8Encoding().GetBytes(item + "\r\n");
// fs.Write(bytes, 0, bytes.Length);
// }
// bytesElement = new UTF8Encoding().GetBytes("没找到shader的材质: " + "\r\n");
// fs.Write(bytesElement, 0, bytesElement.Length);
// foreach (var item in noEnvenSameNameMat)
// {
// byte[] bytes = new UTF8Encoding().GetBytes(item + "\r\n");
// fs.Write(bytes, 0, bytes.Length);
// }
// byte[] bytesEnd = new UTF8Encoding().GetBytes("\r\n");
// fs.Write(bytesEnd, 0, bytesEnd.Length);
//}
//#endregion
#region ExportAndSplit
static void ExportShaderVariantAndSplit()
{
Debug.Log("ExportShaderVariantAndSplit +++ ------------");
ShaderVariantCollectionExporter.Export();
ShaderVariantCollection svc = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Shader/SVC_T.shadervariants")[0] as ShaderVariantCollection;
if (Directory.Exists(Application.dataPath + "/Snowstorm/Shader/ShaderVariantBank"))
{
Directory.Delete(Application.dataPath + "/Snowstorm/Shader/ShaderVariantBank", true);
Debug.Log("删除shaderVariantBank文件夹");
}
if (!Directory.Exists(Application.dataPath + "/Snowstorm/Shader/ShaderVariants"))
{
Directory.CreateDirectory(Application.dataPath + "/Snowstorm/Shader/ShaderVariants");
Debug.Log("删除shaderVariants文件夹");
}
SplitShaderVariantsCollectionEditor.SplitShaderVariantCollection(svc);
Debug.Log("All Succeed, please look at txt !!");
}
#endregion
}
}
















