public static void MakeAtlasReplaceWithCloth(GameObject pObj, string sParentFolder) { #region Step0: Count Progress int iMC = (int)ECharactorMainColor.ECMC_Max; int iSC = (int)ECharactorSubColor.ECSC_Max + 1; List <string[]> combineList = GetHumanoidCombineList(); int iProgressCount = pObj.GetComponentsInChildren <MeshRenderer>(true).Length + combineList.Count; int iProgressFull = iProgressCount * (2 + 3 * iMC * iSC); int iProgressNow = 0; #endregion #region Step1: make gameobject table and make dirs (1x) CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Textures/?"); for (int i = 0; i < iMC; ++i) { for (int j = 0; j < iSC; ++j) { CommonFunctions.CreateFolder(Application.dataPath + "/" + sParentFolder + "/Resources/CharMesh/" + string.Format("M{0}S{1}/?", i, j)); } } List <SCharRendererFullInfo> info = new List <SCharRendererFullInfo>(); Dictionary <string, Texture2D[]> contextureCombine = new Dictionary <string, Texture2D[]>(); Dictionary <string, int> infoIndex = new Dictionary <string, int>(); foreach (MeshRenderer renderer in pObj.GetComponentsInChildren <MeshRenderer>(true)) { ++iProgressNow; EditorUtility.DisplayProgressBar("正在收集Renderer信息", string.Format("{0}/{1}", iProgressNow, iProgressFull), iProgressNow / (float)iProgressFull); Texture2D mainTex = renderer.sharedMaterial.GetTexture("_MainTex") as Texture2D; Texture2D colorTex = renderer.sharedMaterial.GetTexture("_ColorTex") as Texture2D; Texture2D shaTex = renderer.sharedMaterial.GetTexture("_ShadowTex") as Texture2D; if (null == mainTex || null == colorTex || null == shaTex) { CRuntimeLogger.LogError("有的材质没有贴图: " + CommonFunctions.FindFullName(pObj, renderer.gameObject)); EditorUtility.ClearProgressBar(); return; } string sTextureName = CommonFunctions.BuildStringOrder(new[] { mainTex.name, colorTex.name, shaTex.name }); Mesh mesh = renderer.gameObject.GetComponent <MeshFilter>().sharedMesh; info.Add(new SCharRendererFullInfo { m_sFullTexName = sTextureName, m_pMesh = mesh, m_sMeshFilterName = AssetDatabase.GetAssetPath(mesh), m_sMeshName = mesh.name, m_pObj = renderer.gameObject, m_sObjectPath = CommonFunctions.FindFullName(pObj, renderer.gameObject), m_pMainTexture = mainTex, m_pColorTexture = colorTex, m_pShaTexture = shaTex, m_pCombinedMesh = new Mesh[0], m_bDiscard = false, m_pCombinedMeshObj = null, m_bCombine = false, }); infoIndex.Add(CommonFunctions.FindFullName(pObj, renderer.gameObject), info.Count - 1); if (!contextureCombine.ContainsKey(sTextureName)) { contextureCombine.Add(sTextureName, new[] { mainTex, colorTex, shaTex }); } } iProgressNow = iProgressCount; #endregion #region Step2: make colored textures (20x) CCharactorColor colors = new CCharactorColor(); colors.Load(); Dictionary <string, Texture2D> outTexture = new Dictionary <string, Texture2D>(); for (int i = 0; i < iMC; ++i) { for (int j = 0; j < iSC; ++j) { Color mainC = colors[string.Format("M{0}", i + 1)].m_cColor; Color subC = Color.white * 0.7f; if (j < (int)ECharactorSubColor.ECSC_Max) { subC = colors[string.Format("S{0}", j + 1)].m_cColor; } foreach (KeyValuePair <string, Texture2D[]> kvp in contextureCombine) { ++iProgressNow; EditorUtility.DisplayProgressBar("正在阵营着色", string.Format("{0}/{1}", iProgressNow, iProgressFull), iProgressNow / (float)iProgressFull); Texture2D outPutT = GetTexture2DWithColor(kvp.Value[0], kvp.Value[1], kvp.Value[2], mainC, subC, j == (int)ECharactorSubColor.ECSC_Max); outTexture.Add(string.Format("{0}_M{1}S{2}", kvp.Key, i, j), outPutT); } iProgressNow = (i * iSC + j + 2) * iProgressCount; } } Shader unlit = Shader.Find("Unlit/Texture"); string sPackTextureName = sParentFolder + "/Textures/" + unlit.name.Replace("/", "_").Replace(".", "_"); Dictionary <string, Rect> packed = EditorCommonFunctions.PackTexture(outTexture, sPackTextureName, unlit, EditorCommonFunctions.EPackColorFormat.ForcePng); #endregion #region Step3: Combine Batch (1x) List <string> sDisableList = new List <string>(); foreach (string[] combines in combineList) { ++iProgressNow; EditorUtility.DisplayProgressBar("正在收集合并Batch信息", string.Format("{0}/{1}", iProgressNow, iProgressFull), iProgressNow / (float)iProgressFull); GameObject parent = info[infoIndex[pObj.name + "/" + combines[0]]].m_pObj; SCharRendererFullInfo cmb = new SCharRendererFullInfo { m_sObjectPath = CommonFunctions.FindFullName(pObj, parent.transform.parent.gameObject) + "/", m_bDiscard = false, m_pObj = null, m_pTransfParentPath = pObj.name + "/" + combines[0], m_bCombine = true, }; string sMeshFilterName = ""; List <GameObject> cmbobjs = new List <GameObject>(); List <Mesh> cmbmeshes = new List <Mesh>(); List <string> cmbtextures = new List <string>(); foreach (string t in combines) { if (!sDisableList.Contains(pObj.name + "/" + t)) { sDisableList.Add(pObj.name + "/" + t); } GameObject theObj = info[infoIndex[pObj.name + "/" + t]].m_pObj; cmb.m_sObjectPath += theObj.name; sMeshFilterName += theObj.name; cmbobjs.Add(theObj); cmbmeshes.Add(info[infoIndex[pObj.name + "/" + t]].m_pMesh); cmbtextures.Add(info[infoIndex[pObj.name + "/" + t]].m_sFullTexName); } cmb.m_pCombinedMeshObj = cmbobjs.ToArray(); cmb.m_pCombinedMesh = cmbmeshes.ToArray(); cmb.m_sTextureNames = cmbtextures.ToArray(); cmb.m_sMeshFilterName = sMeshFilterName; info.Add(cmb); } foreach (string namecmbdisable in sDisableList) { info[infoIndex[namecmbdisable]].m_bDiscard = true; } iProgressNow = (2 + iMC * iSC) * iProgressCount; #endregion #region Step4: Create Meshes (20x) Dictionary <string, string> meshDic = CreateMeshes(info.ToArray(), packed, sParentFolder + "/Resources/CharMesh/", iProgressNow, iProgressFull, iMC, iSC); AssetDatabase.Refresh(); iProgressNow = (2 + iMC * iSC * 2) * iProgressCount; #endregion #region Step5: Assemble Game Objects (20x) //Create the matrix for (int i = 0; i < iMC; ++i) { for (int j = 0; j < iSC; ++j) { CreateObj(i, j, info, meshDic, "Assets/" + sPackTextureName + ".mat", pObj, iProgressNow, iProgressFull); iProgressNow = ((2 + iMC * iSC * 2) + ((i * iSC) + j + 1)) * iProgressCount; } } #endregion EditorUtility.ClearProgressBar(); }