/// <summary>
    /// Draws all new textures on atlas texture and creates/updates list of sprite data.
    /// Requires:
    /// textures is not null or empty; texturePositions contain position for every texture starting from indexOfFirstTexturePosition.
    /// Render target is set to desired texture.
    /// </summary>
    /// <param name="textures">Textures to be added to atlas texture.</param>
    /// <param name="texturePositionsFunc">This func should return positions of new textures in AtlasTexture and it will be called with index of element and atlas texture. Positions of new textures to be added should start from index specified by third argument.</param>
    /// <param name="indexOfFirstTexturePosition">Index of position of first texture in texturePositions list.</param>
    /// <param name="fillUnusedPlaces">Whether unused sprites should be swapped with new textures.</param>
    protected void DrawNewTextures(List <Texture> textures, Func <int, Texture, Rect> texturePositionsFunc, int indexOfFirstTexturePosition,
                                   bool fillUnusedPlaces)
    {
        // Mesh we will write to.
        Mesh mesh = new Mesh();

        mesh.MarkDynamic();

        // Initialize the data we need to fill
        Vector3[] positions = new Vector3[4];
        Vector2[] uvs       = new Vector2[4];
        int[]     triangles = new int[6];

        int j = 0;

        for (int i = 0; i < textures.Count; i++)
        {
            DynamicSpriteData spriteData = null;

            if (fillUnusedPlaces)
            {
                // first fill empty places, if there is no more empty places fill unused places
                Rect spritePosition = texturePositionsFunc(i + indexOfFirstTexturePosition, AtlasTexture);
                if (spritePosition.xMax > AtlasTexture.width || spritePosition.yMax > AtlasTexture.height)
                {
                    spriteData = FindFirstUnusedSprite(ref j);
                }
            }

            if (spriteData != null)
            {
                // unused sprite found
                numberOfUnused--;
                Atlas.RenameSprite(spriteData.Name, textures[i].name);
                SetPosition(texturePositionsFunc(j - 1, AtlasTexture), TextureSize, spriteData, positions, 0);
                indexOfFirstTexturePosition--;
            }
            else
            {
                spriteData = new DynamicSpriteData(textures[i].name);
                Atlas.AddSprite(spriteData);

                // Set the positions, and sprite data.
                SetPosition(texturePositionsFunc(i + indexOfFirstTexturePosition, AtlasTexture), TextureSize, spriteData, positions, 0);
            }

            spriteData.Reset();
            spriteData.Acquire();

            // Set the UVs
            SetupUvs(uvs, textures[i]);

            // Set the triangles
            SetTriangles(0, triangles);

            mesh.Clear();
            // Add the data to the mesh
            mesh.vertices  = positions;
            mesh.uv        = uvs;
            mesh.triangles = triangles;

            // Set the texture to render to the new atlas
            AtlasingMaterial.mainTexture = textures[i];
            // Activate the material
            AtlasingMaterial.SetPass(0);

            // Draw the texture to the atlas
            Graphics.DrawMeshNow(mesh, Matrix4x4.identity);
            MarkTextureForReusage();
        }

        // Cleanup the mesh, otherwise it will leak, unity won't do this on his own
        Object.Destroy(mesh);
    }