public void DeleteFiles()
        {
            if (_GUIDs.Count > 0)
            {
                // We need to get the editor path first
                string samplePath = Path.GetDirectoryName(
                    AssetDatabase.GUIDToAssetPath(_GUIDs[0])
                    );
                string editorPath = UnityPathUtils.GetEditorFolder(samplePath);
                //string absEditorPath = UnityPathUtils.RelativeToAbsolute(relEditorPath);

                foreach (string GUID in _GUIDs)
                {
                    AssetDatabase.DeleteAsset(
                        AssetDatabase.GUIDToAssetPath(GUID)
                        );
                }

                if (Directory.Exists(editorPath) &&
                    Directory.GetFiles(editorPath).Length == 0 &&
                    Directory.GetDirectories(editorPath).Length == 0
                    )
                {
                    AssetDatabase.DeleteAsset(editorPath);
                }
            }     // End if
        }         // End DeleteFiles
        private string PromptForNewString(string initPathRel)
        {
            bool   valid      = false;
            string newPathAbs = "";
            string newPathRel = "";

            do
            {
                newPathAbs = EditorUtility.OpenFolderPanel("Choose a target folder", initPathRel, "");

                if (string.IsNullOrEmpty(newPathAbs))
                {
                    // They must have canceled or something
                    newPathRel = initPathRel;
                    valid      = true;
                }
                else
                {
                    newPathRel = UnityPathUtils.AbsoluteToRelative(newPathAbs);

                    valid = UnityPathUtils.IsRelativePath(newPathRel);

                    if (!valid)
                    {
                        EditorUtility.DisplayDialog(
                            title: "Invalid Destination",
                            message: "You must pick a folder within the project's Assets folder!",
                            ok: "OK"
                            );
                    }
                }
            } while(!valid);

            return(newPathRel);
        }
Beispiel #3
0
        /// <summary>
        /// Rebuild the files associated with this type based upon its meta data.
        /// This can potentially delete scripts if the templates don't
        /// explicitly build them.
        ///
        /// Scripts are dumped into the folder pointed to by DominantPath.
        /// </summary>
        /// <param name="newMetaData">
        /// The new metadata to use. This simply means that the new scripts
        /// will use this metadata, and then we'll delete old scripts which
        /// haven't been overriden. It does NOT mean that files will get
        /// renamed.
        /// </param>
        /// <returns>The paths of the new/modified files.</returns>
        public List <string> RebuildFiles(ScriptMetaData newMetaData)
        {
            // We'll save the file paths for later... we can never really
            // trust that things won't get updated after we modify the files.
            string[] origPaths = GUIDs;
            for (int i = 0; i < origPaths.Length; i++)
            {
                origPaths[i] = UnityPathUtils.LocalizeDirectorySeparators(
                    AssetDatabase.GUIDToAssetPath(origPaths[i])
                    );
            }

            List <string> resultFiles = VariableTypeBuilder.CreateNewVariableType(
                newMetaData,
                UnityPathUtils.AbsoluteToRelative(DominantPath),
                overrideExisting: true
                );

            // Once we perform the reset, we'll want to clean up any extra files
            // which were not in our set of templates. If we find any,
            // we'll make sure to delete 'em and get everything cleaned up.
            foreach (string origPath in origPaths)
            {
                if (!resultFiles.Contains(origPath))
                {
                    AssetDatabase.DeleteAsset(origPath);
                }
            }

            return(resultFiles);
        }
		/// <summary>
		/// Given a path, checks if it would be part of the Editor assembly.
		/// (That is, if it has a folder named "Editor" in its path.) If not,
		/// the Editor folder is appended to the path.
		/// 
		/// No checks are done to ensure that the folders actually exist, nor
		/// are any folders created.
		/// </summary>
		/// <returns>
		/// The path to the nearest editor folder.
		/// </returns>
		/// <param name="initPath">Path to closes Editor folder.</param>
		public static string GetEditorFolder(string initPath) {
			string editorPath = "";

			if(!IsInEditorAssembly(initPath)) {
				editorPath = UnityPathUtils.Combine(initPath, "Editor");
			}
			else {
				editorPath = initPath;
			}

			return editorPath;
		}
Beispiel #5
0
 /// <summary>
 /// Tests if the path given is valid and can be stored.
 /// </summary>
 /// <returns>The new path.</returns>
 /// <param name="newPath">New path.</param>
 private static string TestNewPath(string newPath)
 {
     // This function exists because we need to be able to use this
     // logic inside the constructor. However, as a struct, the constructor
     // cannot access the path field.
     newPath = UnityPathUtils.AbsoluteToRelative(newPath);
     if (AssetDatabase.IsValidFolder(newPath))
     {
         return(newPath);
     }
     else
     {
         return("");
     }
 }
		/// <summary>
		/// Converts the given relative path into an absolute path. Note that
		/// this only works for paths that are pointing at the "Assets" folder
		/// of the current project. Otherwise, the original path is returned.
		/// </summary>
		/// <returns>The to absolute.</returns>
		/// <param name="relPath">Rel path.</param>
		public static string RelativeToAbsolute(string relPath) {

			string absPath;

			if(IsRelativePath(relPath)) {
				absPath = relPath.Remove(0, "Assets".Length + 1);
				absPath = absPath.TrimStart(new char[] { '/', '\\' });
				absPath = UnityPathUtils.Combine(Application.dataPath, absPath);
			}
			else {
				absPath = relPath;
			}

			return absPath;
		}
		/// <summary>
		/// Converts the absolute path to a relative path. Note that this path
		/// must be pointing at the project's "Assets" folder. Otherwise,
		/// the original path is returned.
		/// </summary>
		/// <returns>The relative path.</returns>
		/// <param name="absPath">Absolute path.</param>
		public static string AbsoluteToRelative(string absPath) {

			string relPath;

			if(IsAbsoluteProjectPath(absPath)) {
				relPath = absPath.Remove(0, Application.dataPath.Length);
				relPath = relPath.TrimStart(new char[] { '/', '\\' });
				relPath = UnityPathUtils.Combine("Assets", relPath);
			}
			else {
				relPath = absPath;
			}

			return relPath;
		}
        }         // End CreateNewVariableType

        #region File Creation
        /// <summary>
        /// Creates a script from the given template.
        ///
        /// This function does very little checking...it assumes that all names
        /// are valid C# for identifiers.
        ///
        /// Be wary that this may throw exceptions. (See StreamReader.ReadToEnd(),
        /// StreamWriter.Write(), StreamReader's contructor, and StreamWriter's
        /// constructor.)
        ///
        /// This does not issue a refresh, nor does it add any labels.
        /// </summary>
        /// <returns>
        /// The relative path (starting with the project root) to the newly
        /// created file. If it wasn't created (i.e. referability doesn't match
        /// with the types supported by the template), and empty string is
        /// returned instead.
        /// </returns>
        /// <param name="readableName">Human readable name.</param>
        /// <param name="typeName">C# name of type to be supported.</param>
        /// <param name="referability">
        /// Referability mode associated with the C# type named by typeName.
        /// </param>
        /// <param name="template">Info for the template.</param>
        /// <param name="normalPath">Path for non-editor scripts.</param>
        /// <param name="editorPath">Path for editor scripts.</param>
        private static string CreateScriptFromTemplate(
            string readableName,
            string typeName,
            ReferabilityMode referability,
            TemplateInfo template,
            string normalPath,
            string editorPath
            )
        {
            string templatePath = "";               // Path of the template file
            string newFileName  = "";               // Name of the new file
            string newFilePath  = "";               // Full path of new file (including name)

            // Before attempting to copy the template, we'll check if it
            // even matches what we need.
            if (template.IsCompatibleWith(referability))
            {
                templatePath = template.path;

                newFileName = ReplaceTemplatePlaceholders(
                    Path.GetFileNameWithoutExtension(templatePath),
                    readableName, typeName, referability.ToString()
                    ) + ".cs";

                newFilePath = UnityPathUtils.Combine(
                    (template.IsEngineTemplate ? normalPath : editorPath),
                    newFileName
                    );

                if (File.Exists(newFilePath))
                {
                    throw new IOException(newFilePath + " already exists!");
                }

                StreamReader templateReader   = null;
                string       templateContents = "";
                try {
                    // After changing the conde in this block, revise the
                    // exception documentaion above.
                    templateReader   = new StreamReader(templatePath);
                    templateContents = templateReader.ReadToEnd();
                }
                finally {
                    if (templateReader != null)
                    {
                        templateReader.Close();
                    }
                }


                string newScriptContents = ReplaceTemplatePlaceholders(
                    templateContents,
                    readableName, typeName, referability.ToString()
                    );


                StreamWriter scriptWriter = null;
                try {
                    // After changing the conde in this block, revise the
                    // exception documentaion above.
                    scriptWriter = new StreamWriter(newFilePath);
                    scriptWriter.Write(newScriptContents);
                }
                finally {
                    if (scriptWriter != null)
                    {
                        scriptWriter.Close();
                    }
                }
            }             // End if( ... )

            return(newFilePath);
        }         // End CreateScriptFromTemplate
        /// <summary>
        /// Creates the new type of the variable based on the given parameters.
        /// After getting all of the correct templates, they will be copied
        /// into the folder specified by targetPath.
        ///
        /// Some templates must be placed in an Editor folder. If one does not
        /// exist, one might be created. However, this function will avoid
        /// overwriting files. Once it is done, it will refresh the project.
        ///
        /// Note that not all of the listen exceptions may get thrown. There
        /// are others which may get thrown by the file IO methods.
        /// </summary>
        ///
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// Thrown if any of the arguments are invalid. (See each argument
        /// for details.)
        /// </exception>
        ///
        /// <exception cref="System.IO.DirectoryNotFoundException">
        /// If the targetPath is invalid.
        /// </exception>
        ///
        /// <exception cref="System.IO.IOException">
        /// Thrown if the Editor folder cannot be created. Also thrown if any
        /// of the files we run into a pre-existing file.
        /// </exception>
        ///
        /// <param name="readableName">
        /// The human readable name. Must be a legal C# name, and must be legal
        /// when used as a filename. The first character should be uppercase.
        /// If any of the checks fail or if the name is already taken
        /// by another variable object, then an ArgumentOutOfRangeException is
        /// thrown.
        /// </param>
        /// <param name="typeName">
        /// The name of the pre-existing C# type to be represtented. If the
        /// string fails the checks, then an ArgumentOutOfRangeException is thrown.
        /// </param>
        /// <param name="referability">
        /// Whether the C# type refered to by typeName is referable or not.
        /// If ReferabilityMode.Unknown is passed, ArgumentOutOfRangeException is thrown.
        /// </param>
        /// <param name="targetPath">
        /// Path used when attempting to create the new files. If this isn't a
        /// valid path, a DirectoryNotFoundException is thrown. If the
        /// target folder is nested in an Editor folder (or is an Editor folder
        /// itself), a ArgumentOutOfRangeException is thrown instead.
        /// </param>
        public static void CreateNewVariableType(
            string readableName,
            string typeName,
            ReferabilityMode referability,
            string targetPath
            )
        {
            // We'll use this to track any new files we make at any point,
            // which makes it easy to clean up after ourselves if things
            // go awry.
            List <string> newFilePaths = new List <string>();

            string editorPath = UnityPathUtils.GetEditorFolder(targetPath);

            if (!IsValidName(readableName))
            {
                throw new System.ArgumentOutOfRangeException(
                          "readableName",
                          "Either contains invalid characters or could conflict with" +
                          " a C# keyword."
                          );
            }
            else if (ScriptFileManager.IsNameTaken(readableName))
            {
                throw new System.ArgumentOutOfRangeException(
                          "readableName",
                          "Is already taken by another VariableObject type."
                          );
            }
            else if (!IsValidName(typeName))
            {
                throw new System.ArgumentOutOfRangeException(
                          "typeName",
                          "Either contains invalid characters or could conflict with" +
                          " a C# keyword."
                          );
            }
            else if (referability == ReferabilityMode.Unknown)
            {
                throw new System.ArgumentOutOfRangeException(
                          "referability",
                          "Must be something other than ReferabilityMode.unknown."
                          );
            }
            else if (!AssetDatabase.IsValidFolder(targetPath))
            {
                throw new DirectoryNotFoundException(
                          "targetPath must be pointing to a pre-existing folder. If" +
                          " you want to create a new folder to put the scripts in," +
                          " you must do it before calling CreateNewVariableType."
                          );
            }
            else if (UnityPathUtils.IsInEditorAssembly(targetPath))
            {
                // If we tried putting all of our scripts in an Editor folder,
                // it would be mostly pointless because then we cannot use our
                // variable objects in the final build.
                throw new System.ArgumentOutOfRangeException(
                          "targetPath",
                          "Must not be nested in an Editor folder."
                          );
            }
            else if (File.Exists(editorPath) && !AssetDatabase.IsValidFolder(editorPath))
            {
                throw new IOException(
                          editorPath + " exists as a file, so we cannot make a folder there!"
                          );
            }


            // It's still possible that the editor folder doesn't exist.
            // However, we are sure that there isn't a file with that name,
            // so we can go ahead and create it if necessary.
            if (!AssetDatabase.IsValidFolder(editorPath))
            {
                editorPath = AssetDatabase.GUIDToAssetPath(
                    AssetDatabase.CreateFolder(targetPath, "Editor")
                    );

                newFilePaths.Add(editorPath);
            }

            // At this point, everything is valid. Barring some kind of error
            // when writting to the disk, everything should be good to go.
            //
            // The only thing we are not going to check is if the files already
            // exist. We could check this before-hand, but this makes it a bit
            // more complex overall. We don't even gain very much in doing this;
            // we still need to handle an exception thrown by the file-writing
            // code, which may require cleaning up files.
            //
            // We shall build a list of all of the files which we create. That
            // way, we can delete them if something goes wrong.
            //
            //
            // Until after the AssetDatabase.Refresh in the finally block,
            // we cannot rely on Unity's AssetDatabase class. This only works
            // on files which are part of the project. However, if start we
            // refreshing, it'll refresh asynchroniously. Deleting files
            // during a refresh is risky, and may lead to errors and even lock
            // up Unity's reloading mechanisms.
            //
            // Fortunately, C# has enough tools to get the job done.

            try {
                EditorApplication.LockReloadAssemblies();

                foreach (TemplateInfo template in TemplateFileManager.Templates)
                {
                    string newScriptPath = CreateScriptFromTemplate(
                        readableName, typeName, referability,
                        template, targetPath, editorPath
                        );

                    // Add it to the start so that, when iterating through
                    // later on, the new folder would be at the back.
                    if (!string.IsNullOrEmpty(newScriptPath))
                    {
                        newFilePaths.Insert(0, newScriptPath);
                    }
                }         // End foreach(TemplateInfo template in Files.Templates)
            }             // End try
            catch (System.Exception e) {
                foreach (string path in newFilePaths)
                {
                    if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
                    {
                        Directory.Delete(path);
                    }
                    else
                    {
                        File.Delete(path);
                    }

                    if (File.Exists(path + ".meta"))
                    {
                        File.Delete(path + ".meta");
                    }
                }

                throw e;
            }
            finally {
                EditorApplication.UnlockReloadAssemblies();
                AssetDatabase.Refresh();
            }

            SetFileLabels(newFilePaths.ToArray());
        }         // End CreateNewVariableType
Beispiel #10
0
        }         // End CreateNewVariableType

        #region File Creation
        /// <summary>
        /// Creates a script from the given template.
        ///
        /// This function does very little checking...it assumes that all names
        /// are valid C# for identifiers.
        ///
        /// Be wary that this may throw exceptions. (See StreamReader.ReadToEnd(),
        /// StreamWriter.Write(), StreamReader's contructor, and StreamWriter's
        /// constructor.)
        ///
        /// This does not issue a refresh, nor does it add any labels.
        /// </summary>
        /// <returns>
        /// The relative path (starting with the project root) to the newly
        /// created file. If it wasn't created (i.e. referability doesn't match
        /// with the types supported by the template), and empty string is
        /// returned instead.
        /// </returns>
        /// <param name="metaData">Data used to populate the template.</param>
        /// <param name="template">Info for the template.</param>
        /// <param name="normalPath">Path for non-editor scripts.</param>
        /// <param name="editorPath">Path for editor scripts.</param>
        private static string CreateScriptFromTemplate(
            ScriptMetaData metaData,
            TemplateInfo template,
            string normalPath,
            string editorPath,
            bool overrideExisting = false
            )
        {
            //string templatePath = "";   // Path of the template file
            //string newFileName = "";    // Name of the new file
            string newFilePath = "";                // Full path of new file (including name)

            // Before attempting to copy the template, we'll check if it
            // even matches what we need.
            if (template.IsCompatibleWith(metaData.ParsedReferability))
            {
                string templateName = Path.GetFileNameWithoutExtension(template.path);
                string newFileName  = metaData.ApplyReplacements(templateName) + ".cs";

                newFilePath = UnityPathUtils.Combine(
                    (template.IsEngineTemplate ? normalPath : editorPath),
                    newFileName
                    );

                if (File.Exists(newFilePath) && !overrideExisting)
                {
                    throw new IOException(newFilePath + " already exists!");
                }

                StreamReader templateReader   = null;
                string       templateContents = "";
                try {
                    // After changing the conde in this block, revise the
                    // exception documentaion above.
                    templateReader   = new StreamReader(template.path);
                    templateContents = templateReader.ReadToEnd();
                }
                finally {
                    if (templateReader != null)
                    {
                        templateReader.Close();
                    }
                }


                string newScriptContents = metaData.ApplyReplacements(templateContents);


                StreamWriter scriptWriter = null;
                try {
                    // After changing the conde in this block, revise the
                    // exception documentaion above.
                    scriptWriter = new StreamWriter(newFilePath, append: false);
                    scriptWriter.Write(newScriptContents + TemplateNewLine);

                    // Append the meta data.
                    scriptWriter.Write(ScriptSetManager.DataHeader + TemplateNewLine);
                    scriptWriter.Write(metaData.ToJson() + TemplateNewLine);
                    scriptWriter.Write(ScriptSetManager.DataFooter + TemplateNewLine);
                }
                finally {
                    if (scriptWriter != null)
                    {
                        scriptWriter.Close();
                    }
                }
            }             // End if( ... )

            return(newFilePath);
        }         // End CreateScriptFromTemplate
Beispiel #11
0
        /// <summary>
        /// Creates the new type of the variable based on the given parameters.
        /// After getting all of the correct templates, they will be copied
        /// into the folder specified by targetPath.
        ///
        /// Some templates must be placed in an Editor folder. If one does not
        /// exist, one might be created. However, this function will avoid
        /// overwriting files. Once it is done, it will refresh the project.
        ///
        /// Note that not all of the listen exceptions may get thrown. There
        /// are others which may get thrown by the file IO methods.
        /// </summary>
        ///
        /// <exception cref="System.ArgumentOutOfRangeException">
        /// Thrown if any of the arguments are invalid. (See each argument
        /// for details.)
        /// </exception>
        ///
        /// <exception cref="System.IO.DirectoryNotFoundException">
        /// If the targetPath is invalid.
        /// </exception>
        ///
        /// <exception cref="System.IO.IOException">
        /// Thrown if the Editor folder cannot be created. Also thrown if any
        /// of the files we run into a pre-existing file.
        /// </exception>
        ///
        /// <param name="metaData">
        /// All of the data to use for the new scripts.
        ///
        /// metaData.name: Must be a legal C# name, and must be legal
        /// when used as a filename. The first character should be uppercase.
        /// If any of the checks fail or if the name is already taken
        /// by another variable object, then an ArgumentOutOfRangeException is
        /// thrown.
        ///
        /// metaData.type: The name of the pre-existing C# type to be represtented. If
        /// the string fails the checks, then an ArgumentOutOfRangeException is thrown.
        ///
        /// metaData.ParsedReferability: Whether the C# type refered to by typeName is
        /// a class or a struct. If ReferabilityMode.Unknown is passed,
        /// ArgumentOutOfRangeException is thrown.
        /// </param>
        ///
        /// <param name="targetPath">
        /// Path used when attempting to create the new files. If this isn't a
        /// valid path, a DirectoryNotFoundException is thrown. If the
        /// target folder is nested in an Editor folder (or is an Editor folder
        /// itself), a ArgumentOutOfRangeException is thrown instead.
        /// </param>
        ///
        /// <param name="overrideExisting">
        /// If true, this will NOT check for scripts which already exist, and will
        /// happilly override whatever it finds. This will NOT change GUIDs.
        /// </param>
        ///
        /// <returns>A list of all the files created.</returns>
        public static List <string> CreateNewVariableType(
            ScriptMetaData metaData,
            string targetPath,
            bool overrideExisting = false
            )
        {
            // This is the path of the editor folder we'll use to dump our
            // editor scripts into.
            string editorPath = UnityPathUtils.GetEditorFolder(targetPath);

            #region Error checking
            if (!IsValidName(metaData.name))
            {
                throw new System.ArgumentOutOfRangeException(
                          "readableName",
                          "Either contains invalid characters or could conflict with" +
                          " a C# keyword."
                          );
            }
            else if (ScriptSetManager.IsNameTaken(metaData.name) && !overrideExisting)
            {
                throw new System.ArgumentOutOfRangeException(
                          "readableName",
                          "Is already taken by another VariableObject type."
                          );
            }
            else if (!IsValidName(metaData.type))
            {
                throw new System.ArgumentOutOfRangeException(
                          "typeName",
                          "Either contains invalid characters or could conflict with" +
                          " a C# keyword."
                          );
            }
            else if (metaData.ParsedReferability == ReferabilityMode.Unknown)
            {
                throw new System.ArgumentOutOfRangeException(
                          "referability",
                          "Must be something other than ReferabilityMode.unknown."
                          );
            }
            else if (!AssetDatabase.IsValidFolder(targetPath) && !Directory.Exists(targetPath))
            {
                // TODO This seems mildly buggy on Windows. I created a folder
                //      inside the folder-select prompt and it complained about
                //      it. Maybe, instead of using AssetDatabase, we should use
                //      normal C# checks?
                throw new DirectoryNotFoundException(
                          "targetPath must be pointing to a pre-existing folder. If" +
                          " you want to create a new folder to put the scripts in," +
                          " you must do it before calling CreateNewVariableType." +
                          "(Trying to use: " + targetPath + ")"
                          );
            }
            else if (UnityPathUtils.IsInEditorAssembly(targetPath))
            {
                // If we tried putting all of our scripts in an Editor folder,
                // it would be mostly pointless because then we cannot use our
                // variable objects in the final build.
                throw new System.ArgumentOutOfRangeException(
                          "targetPath",
                          "Must not be nested in an Editor folder."
                          );
            }
            else if (File.Exists(editorPath) && !AssetDatabase.IsValidFolder(editorPath))
            {
                throw new IOException(
                          editorPath + " exists as a file, so we cannot make a folder there!"
                          );
            }
            #endregion



            /*
             * At this point, everything is valid. Barring some kind of error
             * when writting to the disk, everything should be good to go.
             *
             * The only thing we are not going to check is if the files already
             * exist. We could check this before-hand, but this makes it a bit
             * more complex overall. We don't even gain very much in doing this;
             * we still need to handle an exception thrown by the file-writing
             * code, which may require cleaning up files.
             *
             * We shall build a list (see newFIlePaths, below) of all of the
             * files which we create. That way, we can delete them if something
             * goes wrong.
             *
             *
             * Until calling AssetDatabase.Refresh in the finally block,
             * we cannot rely on Unity's AssetDatabase class without risking
             * the stability of Unity.
             *
             * If Unity begins a refresh (on its own accord), this process
             * occurs asynchroniously. In other words, it may start refreshing
             * right in the middle of this function execution.
             *
             * This is normally okay, but if we catch an exception, we need
             * to delete all of the files we created. Deleting files during a
             * refresh is risky, and may lead to errors and even lock up
             * Unity's reloading mechanisms, halting the Unity Editor.
             *
             * Fortunately, C# has enough tools to get the job done. Still,
             * it's a bit less robust than using the AssetDatabase. Also, we
             * cannot set labels until the very end of the process.
             *
             * (Again, we can't just check ahead of time. There's always risk
             * of an exception getting thrown while doing file IO.)
             */


            // Used to track the new files we add so that we can clean them up
            // if necessary. This is a stack so that the first most recent
            // things we create get deleted first.
            Stack <string> newFilePaths = new Stack <string>();

            try {
                // It's still possible that the editor folder doesn't exist.
                // However, we are sure that there isn't a file with that name,
                // so we can go ahead and create it if necessary.
                //
                // Note that we're doing this BEFORE locking the assemblies so
                // we can still use the AssetDatabase class.
                if (!AssetDatabase.IsValidFolder(editorPath))
                {
                    editorPath = AssetDatabase.GUIDToAssetPath(
                        AssetDatabase.CreateFolder(targetPath, "Editor")
                        );

                    // We've created the folder, so it's one of the things
                    // we'll want to clean up if things go wrong.
                    newFilePaths.Push(editorPath);
                }


                EditorApplication.LockReloadAssemblies();

                foreach (TemplateInfo template in TemplateFileManager.Templates)
                {
                    string newScriptPath = CreateScriptFromTemplate(
                        metaData, template, targetPath, editorPath, overrideExisting
                        );

                    // CreateScriptFromTemplate CAN return an empty string if
                    // it chooses not to create a script, so we have to watch for this.
                    if (!string.IsNullOrEmpty(newScriptPath))
                    {
                        newFilePaths.Push(newScriptPath);
                    }
                }         // End foreach(TemplateInfo template in Files.Templates)
            }             // End try
            catch (System.Exception e) {
                foreach (string path in newFilePaths)
                {
                    if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
                    {
                        Directory.Delete(path);

                        // Possible Unity created a meta file already.
                        if (File.Exists(path + ".meta"))
                        {
                            File.Delete(path + ".meta");
                        }
                    }
                    else
                    {
                        File.Delete(path);
                    }
                }

                throw e;
            }
            finally {
                EditorApplication.UnlockReloadAssemblies();
                AssetDatabase.Refresh();
            }

            string label = metaData.builtin ? ScriptSetManager.UnityLabel : ScriptSetManager.CustomLabel;
            SetFileLabels(newFilePaths.ToArray(), label);

            return(new List <string>(newFilePaths));
        }         // End CreateNewVariableType