/// <summary>
        /// Creates an asset bundle from the assets located in the processed data directory.
        /// </summary>
        /// <returns></returns> Returns true if the asset bundle was created successfully, false otherwise.
        public bool CreateAssetBundleFromCreatedAssets()
        {
            // Delete previous asset bundle.
            GeneralToolkit.Delete(bundleDirectory);
            // Copy assets to the temporary directory.
            GeneralToolkit.Replace(PathType.Directory, processedDataDirectory, GeneralToolkit.tempDirectoryAbsolutePath);
            AssetDatabase.Refresh();
            // Get the assets' relative path locations.
            string[] assetFullPaths     = Directory.GetFiles(GeneralToolkit.tempDirectoryAbsolutePath);
            string[] assetRelativePaths = new string[assetFullPaths.Length];
            for (int i = 0; i < assetFullPaths.Length; i++)
            {
                assetRelativePaths[i] = GeneralToolkit.ToRelativePath(assetFullPaths[i]);
            }
            // Create an asset bundle from these assets.
            bool success = GeneralToolkit.CreateAssetBundle(bundleDirectory, bundleName, assetRelativePaths);

            // If successful, indicate to the processing information file that the asset bundle was created.
            if (success && File.Exists(processingInfoFilePath))
            {
                File.AppendAllLines(processingInfoFilePath, new string[] { processingInfoSuccessfulBundle });
            }
            // Delete the temporary directory.
            GeneralToolkit.Delete(GeneralToolkit.tempDirectoryAbsolutePath);
            // Refresh the database.
            AssetDatabase.Refresh();
            // Return whether the operation was successful.
            return(success);
        }
        /// <summary>
        /// Coroutine that saves the specified global mesh asset into the asset bundle.
        /// </summary>
        /// <returns></returns>
        private IEnumerator SaveGlobalMeshAsAssetCoroutine()
        {
            // Set the destination paths to a temporary asset folder.
            string bundledAssetName  = GetBundledAssetName(globalMeshAssetName);
            string assetPathAbsolute = GetAssetPathAbsolute(bundledAssetName);
            string assetPathRelative = GetAssetPathRelative(bundledAssetName);

            // Check if the asset has already been processed.
            if (!dataHandler.IsAssetAlreadyProcessed(assetPathRelative))
            {
                // If the mesh to store is already an asset, move it to the asset bundle path.
                string dstExtension = Path.GetExtension(_globalMeshPathAbsolute);
                if (dstExtension == ".asset")
                {
                    // Copy the asset to the destination path.
                    GeneralToolkit.Replace(PathType.File, _globalMeshPathAbsolute, assetPathAbsolute);
                    // Refresh the asset database.
                    AssetDatabase.Refresh();
                }
                // Otherwise, the mesh first has to be converted into an asset.
                else
                {
                    // Copy the mesh to the resources folder.
                    string dstName     = "COLIBRITempResource";
                    string dstFullPath = Path.Combine(COLIBRIVRSettings.settingsResourcesAbsolutePath, dstName + dstExtension);
                    GeneralToolkit.Replace(PathType.File, _globalMeshPathAbsolute, dstFullPath);
                    // Refresh the asset database.
                    AssetDatabase.Refresh();
                    yield return(null);

                    // Make the mesh readable so that colliders can be added.
                    ModelImporter modelImporter = ModelImporter.GetAtPath(GeneralToolkit.ToRelativePath(dstFullPath)) as ModelImporter;
                    modelImporter.isReadable = true;
                    modelImporter.SaveAndReimport();
                    // Load the mesh from resources.
                    Mesh loadedMesh = Resources.Load <Mesh>(dstName);
                    // Copy the mesh by instantiating it.
                    globalMesh = (Mesh)Instantiate(loadedMesh);
                    // Recalculate the mesh's normals and bounds.
                    globalMesh.RecalculateNormals();
                    globalMesh.RecalculateBounds();
                    // Create an asset from the copied mesh.
                    AssetDatabase.CreateAsset(globalMesh, assetPathRelative);
                    AssetDatabase.Refresh();
                    // Delete the mesh that was copied into the resources folder.
                    GeneralToolkit.Delete(dstFullPath);
                }
            }
            Mesh meshAsset = AssetDatabase.LoadAssetAtPath <Mesh>(assetPathRelative);

            globalMesh = (Mesh)Instantiate(meshAsset);
        }
        /// <summary>
        /// Saves the meshes in the scene as a global mesh asset in the data directory.
        /// </summary>
        public void SaveGlobalMesh()
        {
            // Combines the different meshes in the scene into a single asset.
            Mesh outputMesh = new Mesh();

            MeshFilter[]      meshFilters = FindObjectsOfType <MeshFilter>();
            CombineInstance[] combine     = new CombineInstance[meshFilters.Length];
            for (int i = 0; i < meshFilters.Length; i++)
            {
                combine[i].mesh      = meshFilters[i].sharedMesh;
                combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
            }
            outputMesh.CombineMeshes(combine, false);
            // Saves the asset in the data directory.
            string assetName          = "GlobalMesh.asset";
            string relativeAssetPath  = Path.Combine("Assets", assetName);
            string globalAssetPath    = Path.Combine(Path.GetFullPath(Application.dataPath), assetName);
            string newGlobalAssetPath = Path.Combine(dataHandler.dataDirectory, assetName);

            GeneralToolkit.CreateAndUnloadAsset(outputMesh, relativeAssetPath);
            GeneralToolkit.Replace(PathType.File, globalAssetPath, newGlobalAssetPath);
            GeneralToolkit.Delete(globalAssetPath);
            AssetDatabase.Refresh();
        }