示例#1
0
    protected void BuildTextureDataWithFolder()
    {
        #region Step1: Find all files

        string sFolderTx = Application.dataPath + "/"
                           + SceneConstant.m_sArtworkPath
                           + TypeName
                           + SceneConstant.m_sSceneTexturesPath;
        string sFolderDoc = Application.dataPath + "/"
                            + SceneConstant.m_sArtworkPath
                            + TypeName
                            + SceneConstant.m_sDecoratesPath;

        CRuntimeLogger.Log("将从" + sFolderTx + "和" + sFolderDoc + "收集信息");
        DirectoryInfo dirtx  = new DirectoryInfo(sFolderTx);
        DirectoryInfo dirdoc = new DirectoryInfo(sFolderDoc);
        if (!dirtx.Exists || !dirdoc.Exists)
        {
            CRuntimeLogger.LogWarning("你选择目录内容不太对吧!");
            return;
        }

        List <FileInfo> allTextures = new List <FileInfo>();
        allTextures.AddRange(dirtx.GetFiles("*.png", SearchOption.AllDirectories));
        allTextures.AddRange(dirdoc.GetFiles("*.png", SearchOption.AllDirectories));
        List <FileInfo> allModels = dirdoc.GetFiles("*.fbx", SearchOption.AllDirectories).ToList();

        #endregion

        #region Step2: Create SceneType

        CSceneType scenetypes = new CSceneType();
        scenetypes.Load();
        if (null == scenetypes[TypeName])
        {
            CSceneTypeElement newType = scenetypes.CreateElement(TypeName);
            newType.m_bCanRot          = CanRotate;
            newType.m_eEdgeType        = EdgeType;
            newType.m_iCliffType       = CliffType;
            newType.m_bHasGroundOffset = HasGroundOffset;
        }
        else
        {
            scenetypes[TypeName].m_bCanRot          = CanRotate;
            scenetypes[TypeName].m_eEdgeType        = EdgeType;
            scenetypes[TypeName].m_iCliffType       = CliffType;
            scenetypes[TypeName].m_bHasGroundOffset = HasGroundOffset;
        }
        scenetypes.Save();

        #endregion

        #region Step3: Bake Texture Atlas

        Dictionary <int, int>          codes = new Dictionary <int, int>(new IntEqualityComparer());
        Dictionary <string, Texture2D> txDic = new Dictionary <string, Texture2D>();
        foreach (FileInfo fileInfo in allTextures)
        {
            string    sFileName  = CommonFunctions.GetLastName(fileInfo.FullName);
            string[]  twoparts   = sFileName.Split('_');
            string    sAssetPath = "Assets" + fileInfo.FullName.Replace("\\", "/").Replace(Application.dataPath.Replace("\\", "/"), "");
            Texture2D t1         = AssetDatabase.LoadAssetAtPath(sAssetPath, typeof(Texture2D)) as Texture2D;
            txDic.Add(sFileName, (Texture2D)EditorCommonFunctions.GetReadWritable(t1));

            //Check whether is a template texture
            int iCode, iRepeat;
            if (2 == twoparts.Length &&
                !string.IsNullOrEmpty(twoparts[0]) &&
                int.TryParse(twoparts[0].Substring(1, twoparts[0].Length - 1), out iCode) &&
                int.TryParse(twoparts[1], out iRepeat))
            {
                if (codes.ContainsKey(iCode))
                {
                    if (codes[iCode] < iRepeat)
                    {
                        codes[iCode] = iRepeat;
                    }
                }
                else
                {
                    codes.Add(iCode, iRepeat);
                }
            }
        }

        Dictionary <string, Rect> textureDic = EditorCommonFunctions.PackTexture(
            txDic,
            SceneConstant.m_sArtworkPath
            + TypeName
            + SceneConstant.m_sSceneTexturesPath,
            Shader.Find("Mobile/Unlit (Supports Lightmap)"), EditorCommonFunctions.EPackColorFormat.ForcePng);

        #endregion

        #region Step4: Make template

        CSceneGroudTemplate tamplate = new CSceneGroudTemplate {
            m_sSceneType = TypeName
        };

        foreach (KeyValuePair <string, Rect> kvp in textureDic)
        {
            CSceneGroudTemplateElement newGT = tamplate.CreateElement();
            tamplate.ChangeName(newGT.m_sElementName, kvp.Key);
            newGT.m_vUV = CommonFunctions.Rect2V4(kvp.Value);
        }
        tamplate.Save();

        #endregion

        #region Step5: Make Scene Texture

        CSceneTexture newT = new CSceneTexture {
            m_sSceneType = TypeName
        };

        for (int lt = 0; lt < 3; ++lt)
        {
            for (int rt = 0; rt < 3; ++rt)
            {
                for (int rb = 0; rb < 3; ++rb)
                {
                    for (int lb = 0; lb < 3; ++lb)
                    {
                        int  iCode, iRots;
                        bool bFlip;
                        FindCodeAndRot(codes, lt, rt, rb, lb, out iCode, out iRots, out bFlip);
                        if (iCode < 0)
                        {
                            CRuntimeLogger.LogError(string.Format("组合没有找到{0}-{1}-{2}-{3}", lt, rt, rb, lb));
                            return;
                        }

                        CSceneTextureElement newE = newT.CreateElement();

                        int iCode2 = lt * CommonFunctions.IntPow(3, 0)
                                     + rt * CommonFunctions.IntPow(3, 1)
                                     + rb * CommonFunctions.IntPow(3, 2)
                                     + lb * CommonFunctions.IntPow(3, 3);
                        newT.ChangeName(newE.m_sElementName, "T" + iCode2);
                        if (iCode2 != newE.m_iID)
                        {
                            newT.ChangeId(newE.m_iID, iCode2);
                        }

                        newE.m_iTemplate     = iCode;
                        newE.m_iRotNumber    = iRots;
                        newE.m_iTextureCount = codes[iCode];
                        newE.m_bReflect      = bFlip;
                    }
                }
            }
        }

        newT.Save();

        #endregion

        #region Step6: Make Decorate

        Dictionary <int, string> modelTemplates = new Dictionary <int, string>(new IntEqualityComparer());
        Dictionary <int, int>    modelRepeates  = new Dictionary <int, int>(new IntEqualityComparer());
        foreach (FileInfo fileInfo in allModels)
        {
            string   sFileName  = CommonFunctions.GetLastName(fileInfo.FullName);
            string[] twoparts   = sFileName.Split('_');
            string   sAssetPath = "Assets" + fileInfo.FullName.Replace("\\", "/").Replace(Application.dataPath.Replace("\\", "/"), "");

            //Check whether is a template texture
            int iCode, iRepeat;
            if (3 == twoparts.Length &&
                int.TryParse(twoparts[1], out iCode) &&
                int.TryParse(twoparts[2], out iRepeat) &&
                iCode < 3 && iCode >= 0)
            {
                //Make template data
                if (!modelTemplates.ContainsKey(iCode))
                {
                    modelTemplates.Add(iCode, twoparts[0] + "_" + iCode);
                }

                if (!modelRepeates.ContainsKey(iCode))
                {
                    modelRepeates.Add(iCode, iRepeat);
                }
                else if (modelRepeates[iCode] < iRepeat)
                {
                    modelRepeates[iCode] = iRepeat;
                }

                //Make the mesh
                List <Vector3> verts    = new List <Vector3>();
                List <Vector2> uvs      = new List <Vector2>();
                List <int>     trangles = new List <int>();

                GameObject go = AssetDatabase.LoadMainAssetAtPath(sAssetPath) as GameObject;
                if (null != go)
                {
                    foreach (MeshFilter mf in go.GetComponentsInChildren <MeshFilter>(true))
                    {
                        Mesh editablemesh = (Mesh)EditorCommonFunctions.GetReadWritable(mf.sharedMesh);
                        int  iVertCount   = verts.Count;
                        Rect rct;

                        MeshRenderer mr = mf.gameObject.GetComponent <MeshRenderer>();
                        if (null != mr && null != mr.sharedMaterial && null != mr.sharedMaterial.mainTexture &&
                            textureDic.ContainsKey(mr.sharedMaterial.mainTexture.name))
                        {
                            rct = textureDic[mr.sharedMaterial.mainTexture.name];
                        }
                        else if (textureDic.ContainsKey(editablemesh.name))
                        {
                            rct = textureDic[editablemesh.name];
                        }
                        else
                        {
                            CRuntimeLogger.LogWarning("Mesh找不到贴图:" + sAssetPath);
                            return;
                        }

                        if (mf.transform == go.transform)
                        {
                            verts.AddRange(editablemesh.vertices);
                        }
                        else
                        {
                            for (int i = 0; i < editablemesh.vertices.Length; ++i)
                            {
                                Vector3 worldPos = mf.transform.localToWorldMatrix.MultiplyVector(editablemesh.vertices[i]) + mf.transform.position;
                                verts.Add(go.transform.worldToLocalMatrix.MultiplyVector(worldPos - go.transform.position));
                            }
                        }
                        for (int i = 0; i < editablemesh.uv.Length; ++i)
                        {
                            float fX = Mathf.Clamp01(editablemesh.uv[i].x);
                            float fY = Mathf.Clamp01(editablemesh.uv[i].y);
                            uvs.Add(new Vector2(rct.xMin + rct.width * fX, rct.yMin + rct.height * fY));
                        }
                        for (int i = 0; i < editablemesh.triangles.Length; ++i)
                        {
                            trangles.Add(iVertCount + editablemesh.triangles[i]);
                        }
                    }
                }
                Mesh theMesh = new Mesh {
                    vertices = verts.ToArray(), uv = uvs.ToArray(), triangles = trangles.ToArray()
                };
                theMesh.RecalculateNormals();
                Unwrapping.GenerateSecondaryUVSet(theMesh);
                ;
                AssetDatabase.CreateAsset(theMesh, "Assets/"
                                          + SceneConstant.m_sArtworkPath + TypeName
                                          + SceneConstant.m_sDecoratesPath
                                          + "/Generate/" + sFileName + ".asset");
            }
        }

        CSceneDecorate doc = new CSceneDecorate {
            m_sSceneType = TypeName
        };
        CSceneDecorate olddoc = new CSceneDecorate {
            m_sSceneType = TypeName
        };
        olddoc.Load();
        foreach (KeyValuePair <int, string> kvp in modelTemplates)
        {
            CSceneDecorateElement element = doc.CreateElement(kvp.Value);
            if (element.m_iID != kvp.Key)
            {
                doc.ChangeId(element.m_iID, kvp.Key);
            }
            element.m_iDecrateRepeat = modelRepeates[kvp.Key];
            if (null != olddoc[kvp.Key])
            {
                element.m_bBlockPathfinding = olddoc[kvp.Key].m_bBlockPathfinding;
                element.m_iDecrateSize      = olddoc[kvp.Key].m_iDecrateSize;
                element.m_bOnlyRotateY      = olddoc[kvp.Key].m_bOnlyRotateY;
            }
        }
        doc.Save();
        AssetDatabase.Refresh();

        #endregion
    }
    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();
    }