void OnGUI()
        {
            m_scrollPosition = EditorGUILayout.BeginScrollView(m_scrollPosition);
            EditorGUILayout.BeginVertical();
            EditorGUILayout.LabelField("Select the parent object that is to be combined.");

            EditorGUI.BeginChangeCheck();
            m_parentObject = (GameObject)EditorGUILayout.ObjectField("Parent Object Of Meshes To Be Combined", m_parentObject, typeof(GameObject), true);
            if (EditorGUI.EndChangeCheck())
            {
                m_textureAtlasInfo   = new TextureAtlasInfo();
                m_texPropArraySize   = m_textureAtlasInfo.shaderPropertiesToLookFor.Length;
                m_shaderFoldoutBools = new bool[m_texPropArraySize];
            }

            if (m_parentObject != null)
            {
                m_textureAtlasInfo.compressTexturesInMemory = false;//EditorGUILayout.Toggle("Compress Texture", m_textureAtlasInfo.compressTexturesInMemory);

                EditorGUI.BeginChangeCheck();
                m_texPropArraySize = EditorGUILayout.IntSlider("# Of Shader Properties", m_texPropArraySize, 0, 20);
                if (EditorGUI.EndChangeCheck())
                {
                    if (m_texPropArraySize > m_textureAtlasInfo.shaderPropertiesToLookFor.Length)
                    {
                        ShaderProperties[] temp = new ShaderProperties[m_texPropArraySize];

                        for (int i = 0; i < m_texPropArraySize; i++)
                        {
                            if (i < m_textureAtlasInfo.shaderPropertiesToLookFor.Length)
                            {
                                temp [i] = m_textureAtlasInfo.shaderPropertiesToLookFor [i];
                            }
                            else
                            {
                                temp [i] = new ShaderProperties(false, "");
                            }
                        }

                        m_textureAtlasInfo.shaderPropertiesToLookFor = temp;
                    }
                    else if (m_texPropArraySize < m_textureAtlasInfo.shaderPropertiesToLookFor.Length)
                    {
                        ShaderProperties[] temp = new ShaderProperties[m_texPropArraySize];

                        for (int i = 0; i < m_texPropArraySize; i++)
                        {
                            temp [i] = m_textureAtlasInfo.shaderPropertiesToLookFor [i];
                        }

                        m_textureAtlasInfo.shaderPropertiesToLookFor = temp;
                    }

                    m_shaderFoldoutBools = new bool[m_texPropArraySize];
                }

                m_showShaderProperties = EditorGUILayout.Foldout(m_showShaderProperties, "Shader Properties To Watch For");
                if (m_showShaderProperties)
                {
                    for (int i = 0; i < m_texPropArraySize; i++)
                    {
                        m_shaderFoldoutBools [i] = EditorGUILayout.Foldout(m_shaderFoldoutBools [i], "Shader Properties Element " + i);

                        if (m_shaderFoldoutBools [i])
                        {
                            m_textureAtlasInfo.shaderPropertiesToLookFor [i].markAsNormal = EditorGUILayout.Toggle("Mark As Normal Map", m_textureAtlasInfo.shaderPropertiesToLookFor [i].markAsNormal);
                            m_textureAtlasInfo.shaderPropertiesToLookFor [i].propertyName = EditorGUILayout.TextField("Shader Property Name", m_textureAtlasInfo.shaderPropertiesToLookFor [i].propertyName);
                        }
                    }
                }

                GUILayout.Space(m_window.position.height * 0.05f);

                EditorGUI.BeginChangeCheck();
                m_folderPath = EditorGUILayout.TextField("Combined Asset Path", m_folderPath);
                if (EditorGUI.EndChangeCheck())
                {
                    m_pathToAssets = Application.dataPath + "/" + m_folderPath + "/";
                }

                GUILayout.Space(m_window.position.height * 0.05f);

                m_showModelSettings = EditorGUILayout.Foldout(m_showModelSettings, "Model Settings");
                if (m_showModelSettings)
                {
                    GUILayout.Label("Meshes", "BoldLabel");
                    EditorGUILayout.LabelField("Meshes");
                    m_modelImportSettings.globalScale         = EditorGUILayout.FloatField("Global Scale", m_modelImportSettings.globalScale);
                    m_modelImportSettings.meshCompression     = (ModelImporterMeshCompression)EditorGUILayout.EnumPopup("Mesh Compression", m_modelImportSettings.meshCompression);
                    m_modelImportSettings.optimizeMesh        = EditorGUILayout.Toggle("Optimize Mesh", m_modelImportSettings.optimizeMesh);
                    m_modelImportSettings.addCollider         = EditorGUILayout.Toggle("Generate Colliders", m_modelImportSettings.addCollider);
                    m_modelImportSettings.swapUVChannels      = EditorGUILayout.Toggle("Swap UVs", m_modelImportSettings.swapUVChannels);
                    m_modelImportSettings.generateSecondaryUV = EditorGUILayout.Toggle("Generate Lightmap UVs", m_modelImportSettings.generateSecondaryUV);

                    GUILayout.Label("Normals & Tangents", "BoldLabel");

                    m_modelImportSettings.normalImportMode  = (ModelImporterTangentSpaceMode)EditorGUILayout.EnumPopup("Normals", m_modelImportSettings.normalImportMode);
                    m_modelImportSettings.tangentImportMode = (ModelImporterTangentSpaceMode)EditorGUILayout.EnumPopup("Tangents", m_modelImportSettings.tangentImportMode);

                    if ((m_modelImportSettings.normalImportMode == ModelImporterTangentSpaceMode.Calculate) && m_modelImportSettings.tangentImportMode != ModelImporterTangentSpaceMode.None)
                    {
                        m_modelImportSettings.tangentImportMode = ModelImporterTangentSpaceMode.Calculate;
                    }

                    EditorGUI.BeginDisabledGroup(m_modelImportSettings.normalImportMode != ModelImporterTangentSpaceMode.Calculate);
                    m_modelImportSettings.normalSmoothingAngle = EditorGUILayout.IntSlider("Normal Smoothing Angle", (int)m_modelImportSettings.normalSmoothingAngle, 0, 180);
                    EditorGUI.EndDisabledGroup();

                    EditorGUI.BeginDisabledGroup(m_modelImportSettings.tangentImportMode != ModelImporterTangentSpaceMode.Calculate);
                    m_modelImportSettings.splitTangentsAcrossSeams = EditorGUILayout.Toggle("Split Tangents", m_modelImportSettings.splitTangentsAcrossSeams);
                    EditorGUI.EndDisabledGroup();
                }

                m_showTextureSettings = EditorGUILayout.Foldout(m_showTextureSettings, "Texture Settings");
                if (m_showTextureSettings)
                {
                    m_textureImportSettings.textureType = (TextureImporterType)EditorGUILayout.EnumPopup("", m_textureImportSettings.textureType);

                    switch (m_textureImportSettings.textureType)
                    {
                    case TextureImporterType.NormalMap:
                        //m_textureImportSettings.convertToNormalmap = EditorGUILayout.Toggle("", m_textureImportSettings.convertToNormalmap);
                        m_textureImportSettings.heightmapScale  = EditorGUILayout.Slider(m_textureImportSettings.heightmapScale, 0.0f, 0.3f);
                        m_textureImportSettings.normalmapFilter = (TextureImporterNormalFilter)EditorGUILayout.EnumPopup("Normal Map Filter", m_textureImportSettings.normalmapFilter);

                        m_textureImportSettings.wrapMode   = (TextureWrapMode)EditorGUILayout.EnumPopup("Texture Wrap Mode", m_textureImportSettings.wrapMode);
                        m_textureImportSettings.filterMode = (FilterMode)EditorGUILayout.EnumPopup("Texture Filter Mode", m_textureImportSettings.filterMode);
                        m_textureImportSettings.anisoLevel = EditorGUILayout.IntSlider("Aniso Level", m_textureImportSettings.anisoLevel, 0, 10);
                        break;

                    case TextureImporterType.Lightmap:
                        m_textureImportSettings.filterMode = (FilterMode)EditorGUILayout.EnumPopup("Texture Filter Mode", m_textureImportSettings.filterMode);
                        m_textureImportSettings.anisoLevel = EditorGUILayout.IntSlider("Aniso Level", m_textureImportSettings.anisoLevel, 0, 10);
                        break;

                    case TextureImporterType.Reflection:
                        m_textureImportSettings.grayscaleToAlpha = EditorGUILayout.Toggle("Alpha From Grayscale", m_textureImportSettings.grayscaleToAlpha);
                        m_textureImportSettings.filterMode       = (FilterMode)EditorGUILayout.EnumPopup("Texture Filter Mode", m_textureImportSettings.filterMode);
                        m_textureImportSettings.anisoLevel       = EditorGUILayout.IntSlider("Aniso Level", m_textureImportSettings.anisoLevel, 0, 10);
                        break;

                    default:
                        m_textureImportSettings.textureType      = TextureImporterType.Default;
                        m_textureImportSettings.grayscaleToAlpha = EditorGUILayout.Toggle("Alpha From Grayscale", m_textureImportSettings.grayscaleToAlpha);
                        m_textureImportSettings.wrapMode         = (TextureWrapMode)EditorGUILayout.EnumPopup("Texture Wrap Mode", m_textureImportSettings.wrapMode);
                        m_textureImportSettings.filterMode       = (FilterMode)EditorGUILayout.EnumPopup("Texture Filter Mode", m_textureImportSettings.filterMode);
                        m_textureImportSettings.anisoLevel       = EditorGUILayout.IntSlider("Aniso Level", m_textureImportSettings.anisoLevel, 0, 10);
                        break;
                    }

                    m_textureImportSettings.maxTextureSize = (int)(object)EditorGUILayout.EnumPopup((TextureSize)m_textureImportSettings.maxTextureSize);
                    m_textureImportSettings.textureFormat  = (TextureImporterFormat)EditorGUILayout.EnumPopup(m_textureImportSettings.textureFormat);


                    /*mip map stuff*/
                }
                EditorGUILayout.Toggle("Export Assets ", exportAssets);
                GUILayout.Space(m_window.position.height * 0.05f);


                EditorGUILayout.EndVertical();

                EditorGUILayout.BeginHorizontal();

                if (GUILayout.Button("Combine Mesh", GUILayout.Height(m_window.position.height * 0.1f)))
                {
                    combineMesh(exportAssets);
                }



                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.EndScrollView();
        }
        void OnGUI()
        {
            m_scrollPosition = EditorGUILayout.BeginScrollView(m_scrollPosition);
            EditorGUILayout.BeginVertical();
            EditorGUILayout.LabelField("Select the parent object that is to be combined.");

            EditorGUI.BeginChangeCheck();
            m_parentObject = (GameObject)EditorGUILayout.ObjectField("Parent Object Of Meshes To Be Combined", m_parentObject, typeof(GameObject), true);
            if (EditorGUI.EndChangeCheck()) {
                m_textureAtlasInfo = new TextureAtlasInfo();
                m_texPropArraySize = m_textureAtlasInfo.shaderPropertiesToLookFor.Length;
                m_shaderFoldoutBools = new bool[m_texPropArraySize];
            }

            if (m_parentObject != null) {
                m_textureAtlasInfo.compressTexturesInMemory = false;//EditorGUILayout.Toggle("Compress Texture", m_textureAtlasInfo.compressTexturesInMemory);

                EditorGUI.BeginChangeCheck();
                m_texPropArraySize = EditorGUILayout.IntSlider("# Of Shader Properties", m_texPropArraySize, 0, 20);
                if (EditorGUI.EndChangeCheck()) {
                    if (m_texPropArraySize > m_textureAtlasInfo.shaderPropertiesToLookFor.Length) {
                        ShaderProperties[] temp = new ShaderProperties[m_texPropArraySize];

                        for (int i = 0; i < m_texPropArraySize; i++) {
                            if (i < m_textureAtlasInfo.shaderPropertiesToLookFor.Length) {
                                temp [i] = m_textureAtlasInfo.shaderPropertiesToLookFor [i];
                            } else {
                                temp [i] = new ShaderProperties(false, "");
                            }
                        }

                        m_textureAtlasInfo.shaderPropertiesToLookFor = temp;
                    } else if (m_texPropArraySize < m_textureAtlasInfo.shaderPropertiesToLookFor.Length) {
                        ShaderProperties[] temp = new ShaderProperties[m_texPropArraySize];

                        for (int i = 0; i < m_texPropArraySize; i++) {
                            temp [i] = m_textureAtlasInfo.shaderPropertiesToLookFor [i];
                        }

                        m_textureAtlasInfo.shaderPropertiesToLookFor = temp;
                    }

                    m_shaderFoldoutBools = new bool[m_texPropArraySize];
                }

                m_showShaderProperties = EditorGUILayout.Foldout(m_showShaderProperties, "Shader Properties To Watch For");
                if (m_showShaderProperties) {
                    for (int i = 0; i < m_texPropArraySize; i++) {
                        m_shaderFoldoutBools [i] = EditorGUILayout.Foldout(m_shaderFoldoutBools [i], "Shader Properties Element " + i);

                        if (m_shaderFoldoutBools [i]) {
                            m_textureAtlasInfo.shaderPropertiesToLookFor [i].markAsNormal = EditorGUILayout.Toggle("Mark As Normal Map", m_textureAtlasInfo.shaderPropertiesToLookFor [i].markAsNormal);
                            m_textureAtlasInfo.shaderPropertiesToLookFor [i].propertyName = EditorGUILayout.TextField("Shader Property Name", m_textureAtlasInfo.shaderPropertiesToLookFor [i].propertyName);
                        }
                    }
                }

                GUILayout.Space(m_window.position.height * 0.05f);

                EditorGUI.BeginChangeCheck();
                m_folderPath = EditorGUILayout.TextField("Combined Asset Path", m_folderPath);
                if (EditorGUI.EndChangeCheck()) {
                    m_pathToAssets = Application.dataPath + "/" + m_folderPath + "/";
                }

                GUILayout.Space(m_window.position.height * 0.05f);

                m_showModelSettings = EditorGUILayout.Foldout(m_showModelSettings, "Model Settings");
                if (m_showModelSettings) {
                    GUILayout.Label("Meshes", "BoldLabel");
                    EditorGUILayout.LabelField("Meshes");
                    m_modelImportSettings.globalScale = EditorGUILayout.FloatField("Global Scale", m_modelImportSettings.globalScale);
                    m_modelImportSettings.meshCompression = (ModelImporterMeshCompression)EditorGUILayout.EnumPopup("Mesh Compression", m_modelImportSettings.meshCompression);
                    m_modelImportSettings.optimizeMesh = EditorGUILayout.Toggle("Optimize Mesh", m_modelImportSettings.optimizeMesh);
                    m_modelImportSettings.addCollider = EditorGUILayout.Toggle("Generate Colliders", m_modelImportSettings.addCollider);
                    m_modelImportSettings.swapUVChannels = EditorGUILayout.Toggle("Swap UVs", m_modelImportSettings.swapUVChannels);
                    m_modelImportSettings.generateSecondaryUV = EditorGUILayout.Toggle("Generate Lightmap UVs", m_modelImportSettings.generateSecondaryUV);

                    GUILayout.Label("Normals & Tangents", "BoldLabel");

                    m_modelImportSettings.normalImportMode = (ModelImporterTangentSpaceMode)EditorGUILayout.EnumPopup("Normals", m_modelImportSettings.normalImportMode);
                    m_modelImportSettings.tangentImportMode = (ModelImporterTangentSpaceMode)EditorGUILayout.EnumPopup("Tangents", m_modelImportSettings.tangentImportMode);

                    if ((m_modelImportSettings.normalImportMode == ModelImporterTangentSpaceMode.Calculate) && m_modelImportSettings.tangentImportMode != ModelImporterTangentSpaceMode.None) {
                        m_modelImportSettings.tangentImportMode = ModelImporterTangentSpaceMode.Calculate;
                    }

                    EditorGUI.BeginDisabledGroup(m_modelImportSettings.normalImportMode != ModelImporterTangentSpaceMode.Calculate);
                    m_modelImportSettings.normalSmoothingAngle = EditorGUILayout.IntSlider("Normal Smoothing Angle", (int)m_modelImportSettings.normalSmoothingAngle, 0, 180);
                    EditorGUI.EndDisabledGroup();

                    EditorGUI.BeginDisabledGroup(m_modelImportSettings.tangentImportMode != ModelImporterTangentSpaceMode.Calculate);
                    m_modelImportSettings.splitTangentsAcrossSeams = EditorGUILayout.Toggle("Split Tangents", m_modelImportSettings.splitTangentsAcrossSeams);
                    EditorGUI.EndDisabledGroup();
                }

                m_showTextureSettings = EditorGUILayout.Foldout(m_showTextureSettings, "Texture Settings");
                if (m_showTextureSettings) {
                    m_textureImportSettings.textureType = (TextureImporterType)EditorGUILayout.EnumPopup("", m_textureImportSettings.textureType);

                    switch (m_textureImportSettings.textureType) {
                        case TextureImporterType.Bump:
                    //m_textureImportSettings.convertToNormalmap = EditorGUILayout.Toggle("", m_textureImportSettings.convertToNormalmap);
                            m_textureImportSettings.heightmapScale = EditorGUILayout.Slider(m_textureImportSettings.heightmapScale, 0.0f, 0.3f);
                            m_textureImportSettings.normalmapFilter = (TextureImporterNormalFilter)EditorGUILayout.EnumPopup("Normal Map Filter", m_textureImportSettings.normalmapFilter);

                            m_textureImportSettings.wrapMode = (TextureWrapMode)EditorGUILayout.EnumPopup("Texture Wrap Mode", m_textureImportSettings.wrapMode);
                            m_textureImportSettings.filterMode = (FilterMode)EditorGUILayout.EnumPopup("Texture Filter Mode", m_textureImportSettings.filterMode);
                            m_textureImportSettings.anisoLevel = EditorGUILayout.IntSlider("Aniso Level", m_textureImportSettings.anisoLevel, 0, 10);
                            break;
                        case TextureImporterType.Lightmap:
                            m_textureImportSettings.filterMode = (FilterMode)EditorGUILayout.EnumPopup("Texture Filter Mode", m_textureImportSettings.filterMode);
                            m_textureImportSettings.anisoLevel = EditorGUILayout.IntSlider("Aniso Level", m_textureImportSettings.anisoLevel, 0, 10);
                            break;
                        case TextureImporterType.Reflection:
                            m_textureImportSettings.grayscaleToAlpha = EditorGUILayout.Toggle("Alpha From Grayscale", m_textureImportSettings.grayscaleToAlpha);
                            m_textureImportSettings.filterMode = (FilterMode)EditorGUILayout.EnumPopup("Texture Filter Mode", m_textureImportSettings.filterMode);
                            m_textureImportSettings.anisoLevel = EditorGUILayout.IntSlider("Aniso Level", m_textureImportSettings.anisoLevel, 0, 10);
                            break;
                        default:
                            m_textureImportSettings.textureType = TextureImporterType.Image;
                            m_textureImportSettings.grayscaleToAlpha = EditorGUILayout.Toggle("Alpha From Grayscale", m_textureImportSettings.grayscaleToAlpha);
                            m_textureImportSettings.wrapMode = (TextureWrapMode)EditorGUILayout.EnumPopup("Texture Wrap Mode", m_textureImportSettings.wrapMode);
                            m_textureImportSettings.filterMode = (FilterMode)EditorGUILayout.EnumPopup("Texture Filter Mode", m_textureImportSettings.filterMode);
                            m_textureImportSettings.anisoLevel = EditorGUILayout.IntSlider("Aniso Level", m_textureImportSettings.anisoLevel, 0, 10);
                            break;
                    }

                    m_textureImportSettings.maxTextureSize = (int)(object)EditorGUILayout.EnumPopup((TextureSize)m_textureImportSettings.maxTextureSize);
                    m_textureImportSettings.textureFormat = (TextureImporterFormat)EditorGUILayout.EnumPopup(m_textureImportSettings.textureFormat);

                    /*mip map stuff*/
                }
                EditorGUILayout.Toggle("Export Assets ", exportAssets);
                GUILayout.Space(m_window.position.height * 0.05f);

                EditorGUILayout.EndVertical();

                EditorGUILayout.BeginHorizontal();

                if (GUILayout.Button("Combine Mesh", GUILayout.Height(m_window.position.height * 0.1f))) {
                    combineMesh(exportAssets);
                }

                EditorGUILayout.EndHorizontal();
            }

            EditorGUILayout.EndScrollView();
        }
        /**
         *  This function returns two variables:
        -> The tecture atlas
        -> An array of the old textures and their new positions. (Used for UV modification)
        */
        public static Material combine(Material[] combines, out TexturePosition[] texturePositions, TextureAtlasInfo atlasInfo)
        {
            if (atlasInfo == null) {
                Debug.LogError("atlasInfo is null. Try removing and reattaching combine children component");
                texturePositions = null;
                return null;
            }
            if (atlasInfo.shaderPropertiesToLookFor.Length <= 0) {
                Debug.LogError("You need to enter some shader properties to look for into Atlas Info. Cannot combine with 0 properties");
                texturePositions = null;
                return null;
            }
            List<ShaderProperties> properties = new List<ShaderProperties>();

            for (int i = 0; i < atlasInfo.shaderPropertiesToLookFor.Length; i++) {
                if (combines [0].HasProperty(atlasInfo.shaderPropertiesToLookFor [i].propertyName)) {
                    properties.Add(atlasInfo.shaderPropertiesToLookFor [i]);
                }
            }

            texturePositions = new TexturePosition[combines.Length];

            for (int i = 0; i < combines.Length; i++) {
                TexturePosition tempTexturePosition = new TexturePosition();
                tempTexturePosition.textures = new Texture2D[properties.Count];

                for (int j = 0; j < properties.Count; j++) {
                    //Debug.Log((combines[i].GetTexture(properties[j].propertyName) == null) + ", " +  properties[j].propertyName + ", " + combines[i].name);
                    if (combines [i].GetTexture(properties [j].propertyName) == null) {
                        Debug.LogError("Cannot combine textures when using Unity's default material texture");
                        texturePositions = null;
                        return null;
                    }
                    tempTexturePosition.textures [j] = Object.Instantiate(combines [i].GetTexture(properties [j].propertyName)) as Texture2D;
                    tempTexturePosition.textures [j].name = tempTexturePosition.textures [j].name.Remove(tempTexturePosition.textures [j].name.IndexOf("(Clone)", System.StringComparison.Ordinal));

                }

                texturePositions [i] = tempTexturePosition;
            }

            textureQuickSort(texturePositions, 0, texturePositions.Length - 1);

            for (int i = 0; i < texturePositions.Length; i++) {
                for (int j = 1; j < texturePositions[i].textures.Length; j++) {
                    texturePositions [i].textures [j] = scaleTexture(texturePositions [i].textures [j], texturePositions [i].textures [0].width, texturePositions [i].textures [0].height);
                }
            }

            texturePositions [0].position.x = texturePositions [0].position.y = 0;
            texturePositions [0].position.width = texturePositions [0].textures [0].width;
            texturePositions [0].position.height = texturePositions [0].textures [0].height;

            int height = texturePositions [0].textures [0].height;
            int width = texturePositions [0].textures [0].width;

            int widthIndex = width;
            int heightIndex = 0;

            bool useHeightAsReference = true;
            for (int i = 1; i < texturePositions.Length; i++) {
                texturePositions [i].position.x = widthIndex;
                texturePositions [i].position.y = heightIndex;
                texturePositions [i].position.width = texturePositions [i].textures [0].width;
                texturePositions [i].position.height = texturePositions [i].textures [0].height;

                if (useHeightAsReference) {
                    if (widthIndex + texturePositions [i].textures [0].width > width) {
                        width = widthIndex + texturePositions [i].textures [0].width;
                    }

                    heightIndex += texturePositions [i].textures [0].height;

                    if (heightIndex >= height) {
                        useHeightAsReference = false;
                        height = heightIndex;
                        heightIndex = height;

                        widthIndex = 0;
                    }
                } else {
                    if (heightIndex + texturePositions [i].textures [0].height > height) {
                        height = heightIndex + texturePositions [i].textures [0].height;
                    }

                    widthIndex += texturePositions [i].textures [0].width;

                    if (widthIndex >= width) {
                        useHeightAsReference = true;
                        width = widthIndex;
                        widthIndex = width;

                        heightIndex = 0;
                    }
                }
            }

            if (height > width) {
                width = height;
            } else {
                height = width;
            }
            float textureSizeFactor = 1.0f / height;

            Material newMaterial = new Material(combines [0]);

            for (int i = 0; i < properties.Count; i++) {
                Texture2D combinesTextures = new Texture2D(width, height, (atlasInfo.ignoreAlpha && !properties [i].markAsNormal) ? TextureFormat.RGB24 : TextureFormat.ARGB32, true);
                combinesTextures.anisoLevel = atlasInfo.anisoLevel;
                combinesTextures.filterMode = atlasInfo.filterMode;
                combinesTextures.wrapMode = atlasInfo.wrapMode;

                for (int j = 0; j < texturePositions.Length; j++) {
                    combinesTextures.SetPixels((int)texturePositions [j].position.x, (int)texturePositions [j].position.y, texturePositions [j].textures [i].width, texturePositions [j].textures [i].height, texturePositions [j].textures [i].GetPixels());
                }

                combinesTextures.Apply();

                if (atlasInfo.compressTexturesInMemory) {
                    combinesTextures.Compress(true);
                }

                newMaterial.SetTexture(properties [i].propertyName, combinesTextures);
            }

            for (int i = 0; i < texturePositions.Length; i++) {
                texturePositions [i].position.x = texturePositions [i].position.x * textureSizeFactor;
                texturePositions [i].position.y = texturePositions [i].position.y * textureSizeFactor;
                texturePositions [i].position.width = texturePositions [i].position.width * textureSizeFactor;
                texturePositions [i].position.height = texturePositions [i].position.height * textureSizeFactor;
            }

            return newMaterial;
        }
        /**
         *  This function returns two variables:
         * -> The tecture atlas
         * -> An array of the old textures and their new positions. (Used for UV modification)
         */
        public static Material combine(Material[] combines, out TexturePosition[] texturePositions, TextureAtlasInfo atlasInfo)
        {
            if (atlasInfo == null)
            {
                Debug.LogError("atlasInfo is null. Try removing and reattaching combine children component");
                texturePositions = null;
                return(null);
            }
            if (atlasInfo.shaderPropertiesToLookFor.Length <= 0)
            {
                Debug.LogError("You need to enter some shader properties to look for into Atlas Info. Cannot combine with 0 properties");
                texturePositions = null;
                return(null);
            }
            List <ShaderProperties> properties = new List <ShaderProperties>();

            for (int i = 0; i < atlasInfo.shaderPropertiesToLookFor.Length; i++)
            {
                if (combines [0].HasProperty(atlasInfo.shaderPropertiesToLookFor [i].propertyName))
                {
                    properties.Add(atlasInfo.shaderPropertiesToLookFor [i]);
                }
            }

            texturePositions = new TexturePosition[combines.Length];

            for (int i = 0; i < combines.Length; i++)
            {
                TexturePosition tempTexturePosition = new TexturePosition();
                tempTexturePosition.textures = new Texture2D[properties.Count];

                for (int j = 0; j < properties.Count; j++)
                {
                    //Debug.Log((combines[i].GetTexture(properties[j].propertyName) == null) + ", " +  properties[j].propertyName + ", " + combines[i].name);
                    if (combines [i].GetTexture(properties [j].propertyName) == null)
                    {
                        Debug.LogError("Cannot combine textures when using Unity's default material texture");
                        texturePositions = null;
                        return(null);
                    }
                    tempTexturePosition.textures [j]      = Object.Instantiate(combines [i].GetTexture(properties [j].propertyName)) as Texture2D;
                    tempTexturePosition.textures [j].name = tempTexturePosition.textures [j].name.Remove(tempTexturePosition.textures [j].name.IndexOf("(Clone)", System.StringComparison.Ordinal));
                }

                texturePositions [i] = tempTexturePosition;
            }

            textureQuickSort(texturePositions, 0, texturePositions.Length - 1);

            for (int i = 0; i < texturePositions.Length; i++)
            {
                for (int j = 1; j < texturePositions[i].textures.Length; j++)
                {
                    texturePositions [i].textures [j] = scaleTexture(texturePositions [i].textures [j], texturePositions [i].textures [0].width, texturePositions [i].textures [0].height);
                }
            }

            texturePositions [0].position.x      = texturePositions [0].position.y = 0;
            texturePositions [0].position.width  = texturePositions [0].textures [0].width;
            texturePositions [0].position.height = texturePositions [0].textures [0].height;

            int height = texturePositions [0].textures [0].height;
            int width  = texturePositions [0].textures [0].width;

            int widthIndex  = width;
            int heightIndex = 0;

            bool useHeightAsReference = true;

            for (int i = 1; i < texturePositions.Length; i++)
            {
                texturePositions [i].position.x      = widthIndex;
                texturePositions [i].position.y      = heightIndex;
                texturePositions [i].position.width  = texturePositions [i].textures [0].width;
                texturePositions [i].position.height = texturePositions [i].textures [0].height;

                if (useHeightAsReference)
                {
                    if (widthIndex + texturePositions [i].textures [0].width > width)
                    {
                        width = widthIndex + texturePositions [i].textures [0].width;
                    }

                    heightIndex += texturePositions [i].textures [0].height;

                    if (heightIndex >= height)
                    {
                        useHeightAsReference = false;
                        height      = heightIndex;
                        heightIndex = height;

                        widthIndex = 0;
                    }
                }
                else
                {
                    if (heightIndex + texturePositions [i].textures [0].height > height)
                    {
                        height = heightIndex + texturePositions [i].textures [0].height;
                    }

                    widthIndex += texturePositions [i].textures [0].width;

                    if (widthIndex >= width)
                    {
                        useHeightAsReference = true;
                        width      = widthIndex;
                        widthIndex = width;

                        heightIndex = 0;
                    }
                }
            }

            if (height > width)
            {
                width = height;
            }
            else
            {
                height = width;
            }
            float textureSizeFactor = 1.0f / height;

            Material newMaterial = new Material(combines [0]);

            for (int i = 0; i < properties.Count; i++)
            {
                Texture2D combinesTextures = new Texture2D(width, height, (atlasInfo.ignoreAlpha && !properties [i].markAsNormal) ? TextureFormat.RGB24 : TextureFormat.ARGB32, true);
                combinesTextures.anisoLevel = atlasInfo.anisoLevel;
                combinesTextures.filterMode = atlasInfo.filterMode;
                combinesTextures.wrapMode   = atlasInfo.wrapMode;

                for (int j = 0; j < texturePositions.Length; j++)
                {
                    combinesTextures.SetPixels((int)texturePositions [j].position.x, (int)texturePositions [j].position.y, texturePositions [j].textures [i].width, texturePositions [j].textures [i].height, texturePositions [j].textures [i].GetPixels());
                }

                combinesTextures.Apply();


                if (atlasInfo.compressTexturesInMemory)
                {
                    combinesTextures.Compress(true);
                }

                newMaterial.SetTexture(properties [i].propertyName, combinesTextures);
            }

            for (int i = 0; i < texturePositions.Length; i++)
            {
                texturePositions [i].position.x      = texturePositions [i].position.x * textureSizeFactor;
                texturePositions [i].position.y      = texturePositions [i].position.y * textureSizeFactor;
                texturePositions [i].position.width  = texturePositions [i].position.width * textureSizeFactor;
                texturePositions [i].position.height = texturePositions [i].position.height * textureSizeFactor;
            }

            return(newMaterial);
        }