Пример #1
0
        public void SaveAtlasToFile(string pathOfAtlas, List <Texture2D> texturesOfMaterial, List <Vector2> scales, List <Vector2> offsets)
        {
            isTextureReadableList.Clear();
            textureFormatsUnsupported.Clear();
            texturePlatforms.Clear();
            textureImporterFormats.Clear();
            maxTexturesSizes.Clear();
            for (int i = 0; i < texturesOfMaterial.Count; i++)
            {
                bool textureNeedsImporting = false;

                //check if the texture is readable or not, in case is not readable then set it temporarly to readable in order to get the pixels.
                string texturePath = AssetDatabase.GetAssetPath(texturesOfMaterial[i]);
                if (texturePath != "")     //check that the texture is not a generated texture.
                {
                    TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath);
                    isTextureReadableList.Add(textureImporter.isReadable);
                    if (!textureImporter.isReadable)
                    {
                        textureImporter.isReadable = true;
                        textureNeedsImporting      = true;
                    }
                }
                else
                {
                    isTextureReadableList.Add(true);    //texture is a generated texture, no need to reimport
                }

                /*** make texToProcess format understandable regardless the format it comes from and save the state of the texture  ***/
                TextureImporter texImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
                texturePlatforms.Add("");
                maxTexturesSizes.Add(-1);
                textureImporterFormats.Add((texturePath != "") ? texImporter.textureFormat : TextureImporterFormat.ARGB32);//if the texture exists in the project settings use its format, else a readable format by default
                bool unsupportedTextureFormat = !Utils.TextureSupported(texturesOfMaterial[i]);
                textureFormatsUnsupported.Add(unsupportedTextureFormat);
                if (unsupportedTextureFormat)
                {
                    texImporter.textureType = TextureImporterType.Advanced;

                    if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.WebPlayer || EditorUserBuildSettings.activeBuildTarget == BuildTarget.WebPlayerStreamed)
                    {
                        texturePlatforms[i] = "Web";
                    }
                    else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS)
                    {
                        texturePlatforms[i] = "iPhone";
                    }
                    else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android)// || EditorUserBuildSettings.activeBuildTarget == BuildTarget.SamsungTV)
                    {
                        texturePlatforms[i] = "Android";
                    }
                    else if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneOSXIntel || EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneOSXIntel64 ||
                             EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneOSXUniversal || EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows ||
                             EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneLinux || EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneLinux64 ||
                             EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneLinuxUniversal || EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows64)
                    {
                        texturePlatforms[i] = "Standalone";
                    }

                    int maxTexSize = maxTexturesSizes[i];
                    TextureImporterFormat texImporterFormat = textureImporterFormats[i];
                    texImporter.GetPlatformTextureSettings(texturePlatforms[i], out maxTexSize, out texImporterFormat);//save the values
                    texImporter.textureFormat = TextureImporterFormat.ARGB32;
                    maxTexturesSizes[i]       = maxTexSize;
                    textureImporterFormats[i] = texImporterFormat;
                    texImporter.SetPlatformTextureSettings(texturePlatforms[i], maxTexturesSizes[i], TextureImporterFormat.ARGB32);//set to a readabale format
                    textureNeedsImporting = true;
                }
                if (textureNeedsImporting)
                {
                    AssetDatabase.ImportAsset(texturePath, ImportAssetOptions.ForceUpdate);
                }
                /**********************************************************************************************************/
            }

            Texture2D canvas = new Texture2D(atlasWidth, atlasHeight, TextureFormat.ARGB32, false);

            Color[] baseCol = new Color[atlasWidth * atlasHeight];
            for (int i = 0; i < baseCol.Length; i++)
            {
                baseCol[i] = new Color(0, 0, 0, 0);
            }
            canvas.SetPixels(0, 0, atlasWidth, atlasHeight, baseCol);
            for (int i = 0; i < texturesOfMaterial.Count; i++)
            {
                Texture2D texToProcess = texturesOfMaterial[i];
                //textToProcess = AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(texturesOfMaterial[i], typeof(Texture2D)) as Texture2D;//revisar si getassetpath es ""


                //check that the texture has the same size than the first catched texture when atlasing (Normally is _MainTex)
                //if the texture size that we are processing is not the same size of the atlas, then we have to resize the texture.
                if (texToProcess.width != Mathf.RoundToInt(texturePositions[i].width) ||
                    texToProcess.height != Mathf.RoundToInt(texturePositions[i].height))
                {
                    texToProcess = Utils.CopyTexture(texturesOfMaterial[i], TextureFormat.ARGB32);


                    Debug.LogWarning("Resizing texture: " + texturesOfMaterial[i].name + " from " +
                                     texToProcess.width + "x" + texToProcess.height + " to " +
                                     Mathf.RoundToInt(texturePositions[i].width) + "x" + Mathf.RoundToInt(texturePositions[i].height) +
                                     " In order to make it fit in the atlas.");
                    TextureScale.Point(texToProcess, Mathf.RoundToInt(texturePositions[i].width), Mathf.RoundToInt(texturePositions[i].height));
                }
                texToProcess = TileManager.TileTexture(texToProcess, scales[i], offsets[i]);
                Color[] texturePixels = texToProcess.GetPixels();
                if (canvas == null)
                {
                    Debug.LogError("ERROR: Cant bake atlas with multiple materials and an unsupported format, check README.txt on known issues for a workaround. Clear atlas to restore original objects textures");
                    return;
                }
                canvas.SetPixels(Mathf.RoundToInt(texturePositions[i].x),
                                 Mathf.RoundToInt(texturePositions[i].y),
                                 Mathf.RoundToInt(texturePositions[i].width),
                                 Mathf.RoundToInt(texturePositions[i].height),
                                 texturePixels);
                /**********************************************************************************************************/
            }
            canvas.Apply();
            byte[] bytes = canvas.EncodeToPNG();
            File.WriteAllBytes(pathOfAtlas, bytes);

            int nextPowerOfTwoCanvasSize = Mathf.NextPowerOfTwo(canvas.width) < Constants.MaxSupportedUnityTexture ? Mathf.NextPowerOfTwo(canvas.width) : Constants.MaxSupportedUnityTexture;//calculate canvas size

            AssetDatabase.ImportAsset(pathOfAtlas);
            TextureImporter atlasTextureImporter = AssetImporter.GetAtPath(pathOfAtlas) as TextureImporter;

            atlasTextureImporter.maxTextureSize = nextPowerOfTwoCanvasSize;//Set the canvas size automatically

            /**Check if the generated atlas needs to be a normal map, if it needs to be then mark it. we check if it needs by checking texturesOfMaterial[i] importer is a normal map. if it is mark it.****/
            string testTexturePath       = "";
            bool   foundTextureInProject = false;

            for (int i = 0; i < texturesOfMaterial.Count; i++)
            {
                testTexturePath = AssetDatabase.GetAssetPath(texturesOfMaterial[i]);
                if (testTexturePath != "") //we found a texture that resides on the project view, now we can check if is a normal map
                {
                    foundTextureInProject = true;
                    break;
                }
            }
            if (foundTextureInProject)
            {
                TextureImporter textureImporterFlagNormalMap = AssetImporter.GetAtPath(testTexturePath) as TextureImporter;
                if (textureImporterFlagNormalMap.normalmap) //texture is a normal map!, lets mark our atlas as a normal mapped atlas!
                {
                    atlasTextureImporter.textureType = TextureImporterType.Bump;
                    atlasTextureImporter.normalmap   = true;
                    AssetDatabase.ImportAsset(pathOfAtlas);
                }
            }
            else
            {
                Debug.LogWarning("Couldnt know if atlas '" + pathOfAtlas + "' was a normal map, if it was, please set it as a normal map; textures might look weird");
            }
            /**************************************************************************************************************************************************************************************************/

            //after finishing all the reading of the textures, revert the state of each of the textures processed.
            for (int i = 0; i < texturesOfMaterial.Count; i++)
            {
                bool   textureNeedsReimporting = false;
                string texturePath             = AssetDatabase.GetAssetPath(texturesOfMaterial[i]);
                //set the texture as not readable
                if (!isTextureReadableList[i])
                {
                    TextureImporter textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
                    textureImporter.isReadable = false;
                    textureNeedsReimporting    = true;
                    //AssetDatabase.ImportAsset(texturePath);
                }
                if (textureFormatsUnsupported[i])
                {
                    //lets revert to the original texture format
                    TextureImporter textureImporter = AssetImporter.GetAtPath(texturePath) as TextureImporter;
                    textureImporter.textureFormat = textureImporterFormats[i];
                    textureImporter.SetPlatformTextureSettings(texturePlatforms[i], maxTexturesSizes[i], textureImporterFormats[i]);
                    textureNeedsReimporting = true;
                    //AssetDatabase.ImportAsset(texturePath);
                }
                if (textureNeedsReimporting)
                {
                    AssetDatabase.ImportAsset(texturePath);
                }
            }
        }
Пример #2
0
        public static Texture2D TileTexture(Texture2D tex, Vector2 scale, Vector2 offset)
        {
            if (scale == Vector2.one && offset == Vector2.zero)
            {
                return(tex);
            }

            Texture2D canvas        = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);
            Texture2D textureToTile = Utils.CopyTexture(tex, TextureFormat.ARGB32);

            bool invertX = false;
            bool invertY = false;

            float scaleX = scale.x == 0 ? 0.01f : scale.x;

            if (scaleX < 0)
            {
                scaleX *= -1;
                invertX = true;
            }
            float scaleY = scale.y == 0 ? 0.01f : scale.y;

            if (scaleY < 0)
            {
                scaleY *= -1;
                invertY = true;
            }
            float newSizeX = (float)tex.width / scaleX > Constants.MaxTextureSize ? Constants.MaxTextureSize : (float)tex.width / scaleX;
            float newSizeY = (float)tex.height / scaleY > Constants.MaxTextureSize ? Constants.MaxTextureSize : (float)tex.height / scaleY;

            while (true)
            {
                try {
                    TextureScale.Point(textureToTile,
                                       Mathf.RoundToInt(newSizeX),
                                       Mathf.RoundToInt(newSizeY));
                    break;
                } catch (System.OutOfMemoryException) {
                    //if the system we are running this into is out of memory (because of the scaling)
                    //then reduce the tile size until there are no out of memory exceptions
                    newSizeY *= 0.95f;
                    newSizeX *= 0.95f;

                    Debug.LogWarning("Tiling too small, out of memory, reducing tiled texture size..." + (newSizeX * newSizeY));
                }
            }

            int offsetPixelX = (int)((offset.x % 1) * (float)textureToTile.width);
            int offsetPixelY = (int)((offset.y % 1) * (float)textureToTile.height);

            for (int i = 0; i < canvas.width; i++)
            {
                for (int j = 0; j < canvas.height; j++)
                {
                    canvas.SetPixel(i, j, textureToTile.GetPixel(invertX ? (textureToTile.width - 1 - i + offsetPixelX) % textureToTile.width : (i + offsetPixelX) % textureToTile.width,
                                                                 invertY ? (textureToTile.height - 1 - j + offsetPixelY) % textureToTile.height : (j + offsetPixelY) % textureToTile.height));
                }
            }

            canvas.Apply();
            return(canvas);
        }