Automatically add namespace to Unity C# script

4.5k views Asked by At

I'm familiar with the ability to change script template for Unity game engine. However, it is very limited and only allows one keyword: #SCRIPTNAME#.

As project gets more and more complicated, namespaces becomes crucial part. And there's no way to have script generated with appropriate namespace through Create --> C# Script.

Does anyone know any solutions to this?


P.S. I am aware that you can create files with Visual Studio, that automatically get namespace based on location. However, they contain unnecessary parts like Assets.Scripts...

1

There are 1 answers

0
tsvedas On BEST ANSWER

Doing some research online I've found that you can create AssetModificationProcessor with public static void OnWillCreateAsset(string path) method. In this method you can read created script file and replace content using string.Replace (or other methods).

Dwelling deeper into this, I've came with useful Editor script that changes #NAMESPACE# keyword based on script location in the project (all made using my current project structure, so you might need to adjust the script before it works correctly).

In case the link is broken, here's the editor script:

using System.IO;
using UnityEditor;
using UnityEngine;

namespace MyGame.Editor.Assets
{
    public sealed class ScriptAssetKeywordsReplacer : UnityEditor.AssetModificationProcessor
    {
        /// <summary>
        ///  This gets called for every .meta file created by the Editor.
        /// </summary>
        public static void OnWillCreateAsset(string path)
        {
            path = path.Replace(".meta", string.Empty);

            if (!path.EndsWith(".cs"))
            {
                return;
            }

            var systemPath = path.Insert(0, Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets")));

            ReplaceScriptKeywords(systemPath, path);

            AssetDatabase.Refresh();
        }


        private static void ReplaceScriptKeywords(string systemPath, string projectPath)
        {
            projectPath = projectPath.Substring(projectPath.IndexOf("/SCRIPTS/") + "/SCRIPTS/".Length);
            projectPath = projectPath.Substring(0, projectPath.LastIndexOf("/"));
            projectPath = projectPath.Replace("/Scripts/", "/").Replace('/', '.');

            var rootNamespace = string.IsNullOrWhiteSpace(EditorSettings.projectGenerationRootNamespace) ?
                string.Empty :
                $"{EditorSettings.projectGenerationRootNamespace}.";

            var fullNamespace = $"{rootNamespace}{projectPath}";

            var fileData = File.ReadAllText(systemPath);

            fileData = fileData.Replace("#NAMESPACE#", fullNamespace);

            File.WriteAllText(systemPath, fileData);
        }
    }
}

After adding this script under folder named Editor, you need to change c# script template which is located at %EditorPath%/Data/Resources/ScriptTemplates/81-C# Script-NewBehaviourScript.cs.txt. Open this file and add wrap class with

namespace #NAMESPACE#
{
    // All the class template can stay the same
}