using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using BF; using UnityEditor; using UnityEngine; namespace BFEditor.Resource { public class CheckCharacterDiffTools : CharacterTools { static List diffList = new List(); static List errorList = new List(); static List newAddList = new List(); /// /// 检查所有差异以及错误 /// public static string CheckAll() { diffList.Clear(); errorList.Clear(); newAddList.Clear(); if (!CheckPath()) { return ""; } var fbxDirInfo = new DirectoryInfo(importFbxPath); var redundancyTexList = new List(); var differentTexList = new List(); var newAddTexList = new List(); var redundancyFbxList = new List(); var differentFbxList = new List(); var newAddFbxList = new List(); var directories = fbxDirInfo.GetDirectories(); float count = directories.Length; var countDonw = 1f; foreach (var fbxAbPath in fbxDirInfo.GetDirectories()) { EditorUtility.DisplayProgressBar("正在检查差异", fbxAbPath.FullName, countDonw / count); if (CheckSvnModelRules(fbxAbPath.FullName)) { if (CheckIsImport(fbxAbPath.Name)) { var clipCfgList = ReadFrameConfig(Path.Combine(importFbxPath, fbxAbPath.Name, FRAME_CONFIG).Replace("\\", "/")); if (clipCfgList != null) { CheckMainFbxMd5(fbxAbPath.Name); CheckMainFbxAnimation(fbxAbPath.Name); CheckOtherFbxDifference(fbxAbPath.Name, redundancyFbxList, differentFbxList, newAddFbxList); CheckTexDifference(fbxAbPath.Name, redundancyTexList, differentTexList, newAddTexList); } } } countDonw++; } CheckRedundancyFolder(); var sb = new StringBuilder(); sb.Append("\n"); sb.Append("新增模型" + "\n\n"); foreach (var name in newAddList) { sb.Append(name + "\n"); } sb.Append("\n"); sb.Append("svn错误规范" + "\n\n"); foreach (var name in errorList) { sb.Append(name + "\n"); } sb.Append("\n"); sb.Append("差异列表" + "\n\n"); foreach (var name in diffList) { sb.Append(name + "\n"); } sb.Append("\n\n"); //贴图和其他模型冗余 foreach (var redundancy in redundancyTexList) { sb.Append("unity中的贴图冗余 :" + redundancy + "\n"); } foreach (var diff in differentTexList) { sb.Append("贴图存在差异 :" + diff + "\n"); } foreach (var newAdd in newAddTexList) { sb.Append("新增贴图 :" + newAdd + "\n"); } foreach (var redundancy in redundancyFbxList) { sb.Append("unity中的附属Fbx冗余 :" + redundancy + "\n"); } foreach (var diff in differentFbxList) { sb.Append("附属Fbx存在差异 :" + diff + "\n"); } foreach (var newAdd in newAddFbxList) { sb.Append("附属新增模型 :" + newAdd + "\n"); } var txtName = "差异检查结果.txt"; var txtPath = Path.Combine(importRootPath, txtName).Replace("\\", "/"); if (File.Exists(txtPath)) { File.Delete(txtPath); } File.WriteAllText(txtPath, sb.ToString()); sb.Clear(); //窗口信息 sb.Append("\n"); sb.Append("新增模型数量 : " + newAddList.Count + "\n"); sb.Append("\n"); sb.Append("svn错误规范数量 : " + errorList.Count + "\n"); sb.Append("\n"); sb.Append("差异列表数量 : " + diffList.Count + "\n"); sb.Append("\n"); sb.Append("unity中的贴图冗余数量 : " + redundancyTexList.Count + "\n"); sb.Append("\n"); sb.Append("贴图存在差异数量 : " + differentTexList.Count + "\n"); sb.Append("\n"); sb.Append("新增贴图数量 : " + newAddTexList.Count + "\n"); sb.Append("\n"); sb.Append("unity中的附属Fbx冗余数量 : " + redundancyFbxList.Count + "\n"); sb.Append("\n"); sb.Append("附属Fbx存在差异数量 : " + differentFbxList.Count + "\n"); sb.Append("\n"); sb.Append("附属新增模型数量 : " + newAddFbxList.Count + "\n"); EditorUtility.ClearProgressBar(); return sb.ToString(); } /// /// 检查Root路径完整 /// public static bool CheckPath() { if (!Directory.Exists(importRootPath)) { EditorUtility.DisplayDialog("提示", "选择的导入路径不存在", "ok"); return false; } if (!Directory.Exists(importFbxPath)) { EditorUtility.DisplayDialog("提示", "导入模型路径不存在", "ok"); return false; } if (!Directory.Exists(importTexturePath)) { EditorUtility.DisplayDialog("提示", "导入贴图路径不存在", "ok"); return false; } return true; } /// /// 检查svn单个模型规范 /// public static bool CheckSvnModelRules(string abPath) { if (!Directory.Exists(abPath)) { Debug.LogError("不存在文件夹 :" + abPath); return false; } var modelName = GetDirNameByPath(abPath); //检查帧数表 var clipCfgList = ReadFrameConfig(Path.Combine(abPath, FRAME_CONFIG).Replace("\\", "/")); if (clipCfgList == null) { Debug.LogWarning("帧数表不存在 不进行导入:" + Path.Combine(abPath, FRAME_CONFIG).Replace("\\", "/")); return false; } //检查有无对应贴图文件夹 var textureDir = Path.Combine(importTexturePath, modelName).Replace("\\", "/"); if (!Directory.Exists(textureDir)) { errorList.Add("没有对应的贴图文件夹 :" + Path.Combine(importTexturePath, modelName).Replace("\\", "/")); return false; } //检查有无贴图 var pngs = Directory.GetFiles(textureDir,"*.*").Where(s => s.EndsWith(".png") || s.EndsWith(".tga"));; var countDown = 0; foreach (var p in pngs) { countDown ++; } if (countDown == 0) { errorList.Add("贴图文件夹中没有贴图 :" + textureDir); return false; } //检查有无对名称的fbx if (!File.Exists(Path.Combine(importFbxPath, modelName, modelName + ".fbx").Replace("\\", "/")) && File.Exists(Path.Combine(importFbxPath, modelName, modelName + ".FBX").Replace("\\", "/"))) { errorList.Add("没有与文件夹对应的fbx或者FBX :" + Path.Combine(importFbxPath, modelName, modelName + ".fbx").Replace("\\", "/")); return false; } return true; } /// /// 检查模型是否导入过 /// /// /// public static bool CheckIsImport(string fullName) { var fbxName = GetDirNameByPath(fullName); var unityFbxPath = Path.Combine(UNITY_FBX_PATH, fbxName).Replace("\\", "/"); if (Directory.Exists(unityFbxPath)) { return true; } var clipCfgList = ReadFrameConfig(Path.Combine(importFbxPath, fbxName, FRAME_CONFIG).Replace("\\", "/")); if (clipCfgList != null) { newAddList.Add("新增导入模型 :" + fbxName); return false; } return true; } /// /// 检查主模型MD5 /// /// /// public static bool CheckMainFbxMd5(string fbxName) { var unityFbxPath = Path.Combine(UNITY_FBX_PATH, fbxName, fbxName + ".fbx").Replace("\\", "/"); var unityFbxPath1 = Path.Combine(UNITY_FBX_PATH, fbxName, fbxName + ".FBX").Replace("\\", "/"); var importFbxPath1 = Path.Combine(importFbxPath, fbxName, fbxName + ".fbx").Replace("\\", "/"); var importFbxPath2 = Path.Combine(importFbxPath, fbxName, fbxName + ".fbx").Replace("\\", "/"); var unityFbxMd5 = ""; if (!File.Exists(unityFbxPath)) { if (File.Exists(unityFbxPath1)) { unityFbxMd5 = GameLaunchUtils.GetFileMD5(unityFbxPath1); } else { Debug.LogWarning("unity中不存在模型 :" + fbxName); return true; } } else { unityFbxMd5 = GameLaunchUtils.GetFileMD5(unityFbxPath); } if ((!File.Exists(importFbxPath1)) && (!File.Exists(importFbxPath2))) { errorList.Add("svn中不存在模型" + fbxName); return false; } var importFbxMd5 = GameLaunchUtils.GetFileMD5(importFbxPath1); if (unityFbxMd5 != importFbxMd5) { diffList.Add("主模型md5差异 :" + fbxName); return true; } else { return false; } } /// /// 检查主模型动画文件差异 /// /// /// public static bool CheckMainFbxAnimation(string fbxName) { var clipCfgList = ReadFrameConfig(Path.Combine(importFbxPath, fbxName, FRAME_CONFIG).Replace("\\", "/")); var unityModelPath = Path.Combine(UNITY_FBX_PATH, fbxName, fbxName + ".fbx").Replace("\\", "/"); var unityModelPath1 = Path.Combine(UNITY_FBX_PATH, fbxName, fbxName + ".FBX").Replace("\\", "/"); //检查动画数量 var modelImporter = AssetImporter.GetAtPath(unityModelPath) as ModelImporter; if (modelImporter == null) { modelImporter = AssetImporter.GetAtPath(unityModelPath1) as ModelImporter; if (modelImporter == null) { Debug.LogWarning("unity中不存在模型 :" + unityModelPath); return true; } } var total = clipCfgList.Count; if (total != modelImporter.clipAnimations.Length) { diffList.Add(fbxName + " 帧数表和unity导入的动画数量不一样"); return true; } var tmp = 0; modelImporter.importAnimation = true; //检查动画帧数 for (var i = 0; i < total; i++) { if (modelImporter.clipAnimations[i].firstFrame != clipCfgList[i].startFrame) { diffList.Add(fbxName + " " + clipCfgList[i].name + ": 开始帧有差异 " + " 帧数表 firstFrame : " + clipCfgList[i].startFrame + " Unity firstFrame : " + modelImporter.clipAnimations[i].firstFrame); tmp++; } if (modelImporter.clipAnimations[i].lastFrame != clipCfgList[i].endFrame) { diffList.Add(fbxName + " " + clipCfgList[i].name + ": 结束帧有差异 " + " 帧数表 lastFrame : " + clipCfgList[i].endFrame + " Unity lastFrame : " + modelImporter.clipAnimations[i].lastFrame); tmp++; } if (modelImporter.clipAnimations[i].name != clipCfgList[i].name) { diffList.Add(fbxName + ": 动画name有差异 " + " 帧数表 animationName : " + clipCfgList[i].name + " Unity animationName : " + modelImporter.clipAnimations[i].name); tmp++; } } modelImporter.importAnimation = false; if (tmp > 0) { return true; } Debug.LogWarning("帧数表没有差异 :" + Path.Combine(importFbxPath, fbxName, FRAME_CONFIG).Replace("\\", "/")); return false; } /// /// 检查主模型文件夹中其他fbx差异 /// /// /// public static void CheckOtherFbxDifference(string fbxName, List redunndancyList, List differentList, List newAddList) { var unityFbxDir = Path.Combine(UNITY_FBX_PATH, fbxName).Replace("\\", "/"); var importFbxDir = Path.Combine(importFbxPath, fbxName).Replace("\\", "/"); if (!Directory.Exists(unityFbxDir)) { Debug.LogError("不存在文件夹 :" + unityFbxDir); return; } var unityFbxFileInfo = Directory.GetFiles(unityFbxDir, "*.*").Where(s => s.EndsWith(".fbx") || s.EndsWith(".FBX")); var importFbxFileInfo = Directory.GetFiles(importFbxDir, "*.*").Where(s => s.EndsWith(".fbx") || s.EndsWith(".FBX")); //检查冗余 foreach (var unityFbx in unityFbxFileInfo) { var unityName = Path.GetFileNameWithoutExtension(unityFbx); if (unityName == fbxName) { //主模型 continue; } var flag = false; foreach (var importFBx in importFbxFileInfo) { var importName = Path.GetFileNameWithoutExtension(importFBx); if (unityName == importName) { flag = true; //对比md5 var unityFbxMd5 = GameLaunchUtils.GetFileMD5(unityFbx.Replace("\\", "/")); var importFBxMd5 = GameLaunchUtils.GetFileMD5(importFBx.Replace("\\", "/")); if (unityFbxMd5 != importFBxMd5) { differentList.Add(importFBx.Replace("\\", "/")); } } } if (!flag) { //unity中的冗余Fbx redunndancyList.Add(unityFbx.Replace("\\", "/")); } } //检查新增 foreach (var importFbx in importFbxFileInfo) { var importName = Path.GetFileNameWithoutExtension(importFbx); if (importName == fbxName) { //主模型 continue; } var flag = false; foreach (var unityFbx in unityFbxFileInfo) { var unityName = Path.GetFileNameWithoutExtension(unityFbx); if (unityName == importName) { flag = true; } } if (!flag) { newAddList.Add(importName.Replace("\\", "/")); } } } public static void CheckTexDifference(string fbxName,List redunndancyList, List differentList, List newAddList) { var unityTexDir = Path.Combine(UNITY_FBX_PATH, fbxName, "textures").Replace("\\", "/"); var importTexDir = Path.Combine(importTexturePath, fbxName).Replace("\\", "/"); if (!Directory.Exists(unityTexDir)) { Debug.LogError("不存在文件夹 :" + unityTexDir); return; } var unityTexFileInfo = Directory.GetFiles(unityTexDir,"*.*").Where(s => s.EndsWith(".png") || s.EndsWith(".tga"));; var importTexFileInfo = Directory.GetFiles(importTexDir,"*.*").Where(s => s.EndsWith(".png") || s.EndsWith(".tga"));; //检查冗余 foreach (var unityTex in unityTexFileInfo) { var flag = false; foreach (var importTex in importTexFileInfo) { if (Path.GetFileNameWithoutExtension(unityTex) == Path.GetFileNameWithoutExtension(importTex)) { flag = true; //对比md5 var unityTexMd5 = GameLaunchUtils.GetFileMD5(unityTex.Replace("\\", "/")); var importTexMd5 = GameLaunchUtils.GetFileMD5(importTex.Replace("\\", "/")); if (unityTexMd5 != importTexMd5) { differentList.Add(importTex.Replace("\\", "/")); } } } if (!flag) { //unity中的冗余贴图 redunndancyList.Add(unityTex.Replace("\\", "/")); } } //检查新增 foreach (var importTex in importTexFileInfo) { var flag = false; foreach (var unityTex in unityTexFileInfo) { if (Path.GetFileNameWithoutExtension(unityTex) == Path.GetFileNameWithoutExtension(importTex)) { flag = true; } } if (!flag) { newAddList.Add(importTex.Replace("\\", "/")); } } } static void CheckRedundancyFolder() { var dirInfo = new DirectoryInfo(importFbxPath); var fbxDirs = dirInfo.GetDirectories(); var unityModelDic = new DirectoryInfo(UNITY_FBX_PATH); var dics = unityModelDic.GetDirectories(); var length = dics.Length; for (var i = 0; i < length; i++) { var name = dics[i].Name; var tmpFlag = false; foreach (var fbxDir in fbxDirs) { if (name == fbxDir.Name) { tmpFlag = true; } } if (!tmpFlag) { diffList.Add("冗余模型 (将会删除unity中所有与之相关的文件夹) :" + dics[i].FullName); } } } } }