How to create your own C# Script Template?

Hi guys,

Any idea how do I create my own C# Script Template? So when I go to my context menu Create > C# Script I can select my own type.

So far I’ve been able to find how to modify existing script templates but not implementing your own.

Any ideas?

Thanks! :slight_smile:

I’m not aware of any trivially easy way to do it, but it wouldn’t be overly hard to create a static class script within an Editor folder and attaching the MenuItem attribute to a static function that executes whatever code you desire when the menu item is selected. You could then either use System.IO.File stuff to copy a file template, or System.IO.FileStream to write out a file either directly from string literals in code or from another file stream reading in and altering the template.

It’s still not perfect, because it doesn’t automatically select the asset and put it in rename mode, but you can at least do the selection part with the following:

Selection.activeObject = asset;
EditorApplication.delayCall += () => { EditorUtility.FocusProjectWindow(); };

You’ll need to get the asset object to do so, though, which I believe you can do using AssetDatabase.LoadAssetAtPath(path, type) after you’ve created it. You’ll want to use MonoBehaviour or ScriptableObject for the type, I believe, whichever matches the script type. Can’t recall if you also need to call AssetDatabase.Refresh() before you try loading it.

2 Likes

@AndyGainey Making my own Editor script with a MenuItems attribute is what I am guessing I should be doing, however, I want to be able to name my script without having to manually rename it in IDE.

@LaneFox Thank you, however, I am trying to create my own script template instead of modifying existing ones, so this is not suitable for me.

Haven’t tried it but this might work.

1 Like

Create a class as an Editor script.

On it have a static method shaped ‘static void YourMethod(MenuCommand cmd)’

Attribute it with the ‘MenuItemAttribute’, naming it “Assets/Create My Custom C# Script”.

In said code get the folder based on the active selection (Selection.activeObject), and create a new file based on your own template you have stored somewhere (system System.IO file copy commands, or AssetDatabase.CopyAsset commands… AssetDatabase automatically refreshes the assets).

Something like this:

using UnityEditor;

using System.IO;

public class CustomMenuEntries
{
    public const string PATH_TO_MYSCRIPT_TEMPLATE = @"D:\zTemp\Template.cs";

    [MenuItem("Assets/Create My Custom C# Script")]
    public static void CreateCustomScript(MenuCommand cmd)
    {
        if (Selection.activeObject == null);
        var path = AssetDatabase.GetAssetPath(Selection.activeObject);
        if (File.Exists(path))
            path = Path.GetDirectoryName(path);
        if (string.IsNullOrEmpty(path)) path = "Assets/";


        File.Copy(PATH_TO_MYSCRIPT_TEMPLATE, Path.Combine(path, "NewScript.cs"));
        AssetDatabase.Refresh();

    }
}
3 Likes

In the end, I wrote a small editor script which creates a file with a .cs extension and manually writes each line of code. Been pain in the neck to get it done correctly, but results are perfect. With this method, I can specify the name of the script, as well some other custom attributes. The whole process is automatic.

In case somebody wants to make their own script, I used this code snippet: Editor script need to create Class Script automatically - Questions & Answers - Unity Discussions

Thanks for helping me everyone :slight_smile:

2 Likes

On my Mac the “ScriptTemplates” folder is located inside the “Resources” folder inside the app bundle. Just copy one of the existing ones & give it a new name (and edit it of course). Relaunch Unity and wham, done. I’ve got all my custom scripts in a folder on my desktop & its the first thing I do after installing a new Unity version. I found the same folder on my PC but honestly I can’t remember where it was located.

I have a singleton, scriptableobject & a couple of other templates.
Edit: Added screenshots
2986665--222309--ModifiedCreate.png
2986665--222310--TemplateFolder.png

3 Likes

I found a truly perfect method, hoping to help the next person searching for this problem.

UnityEditor already implements the ability to create and name scripts, so just find out about this function and call it like this:
CreateScriptAsset("Assets/YourTemplatesScript.cs.txt", "DefaultNewScriptName.cs");

Need to add the following code to call it:

7 Likes

This may not be the neatest solution, but maybe it will work well in some cases: in Visual Studio, you can create your own code snippets.

It looks a bit messy (in my humble opinion) with the XML involved, but one nice thing about this method is having the ability to put insert-time replacements in there. You can see this in action if you type foreach and then tab around the replacements (var, item and collection).

@johnsoncodehk Many Thanks! Great elegant find! Thanks so much for posting that.

Small micro-optimization, you only need to do the reflection once to get the method, not every time you call CreateScriptAsset(). i.e:

    private static MethodInfo createScriptMethod = typeof(ProjectWindowUtil)
        .GetMethod("CreateScriptAsset", BindingFlags.Static | BindingFlags.NonPublic);

    static void CreateScriptAsset(string templatePath, string destName) {
      createScriptMethod.Invoke(null, new object[] { templatePath, destName });
    }
1 Like

If you want to use CreateScriptAsset() and are making a package for the Unity2018.2 package manager you need to use the packages path. Which can be found by:

  1. Including the package in a project
  2. Right clicking the template source file
  3. Select “Copy Path”
  4. Paste the path you just copied to where you need it. It’ll be in the format “Packages/com.[company].[project]/Package/Folder/Structure/ScriptTemplate.cs.txt”
  1. Create Assets/ScriptTemplates to override built-in templates on a per-project basis.
  2. Reopen the project
7 Likes

No longer for Unity 2018.2 at least. The path is now “~\Unity\Editor\Data\Resources\ScriptTemplates”. If you want to modify the look of the new c sharp scripts on creation, edit “81-C# Script-NewBehaviourScript.cs.txt” to your liking. :slight_smile:

Before:

3902701--332302--before.JPG

After:

3902701--332308--after.JPG

2 Likes

this works well, except the name of the class in the new script follows what’s in the template. tips on how to make it follow the name you give the new file? cheers!

Sorry if I understand the wrong question.
You can replace the class name with #SCRIPTNAME#, for example:
https://github.com/Unity-Technologies/2d-extras/blob/master/Editor/Tiles/RuleTile/ScriptTemplates/NewCustomRuleTile.cs.txt

1 Like

perfect, cheers!

hello, i’m trying to create iruntime… how i should be able to create my script by template then add it to an object?

There’s an easier version than using Reflection. Just use UnityEditor.ProjectWindowUtil.CreateScriptAssetFromTemplateFile(string pathToTemplateTxtFile, string defaultNewScriptName) instead.

Example:

C# editor-script for making a new right click command and create the new script file:

//ATTENTION: Put this script file into an "Editor"-folder for it to work properly.

using UnityEditor;

public class CreateNewScriptClassFromCustomTemplate
{
    private const string pathToYourScriptTemplate = "Assets/YourScriptTemplatesFolder/YourTemplateScript.cs.txt";

    [MenuItem(itemName: "Assets/Create/Create New Script from Custom Template", isValidateFunction: false, priority: 51)]
    public static void CreateScriptFromTemplate()
    {
        ProjectWindowUtil.CreateScriptAssetFromTemplateFile(pathToYourScriptTemplate, "YourDefaultNewScriptName.cs");
    }
}

And “YourTemplateScript.cs.txt” should look something like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace YourNamespace
{
    public class #SCRIPTNAME# : MonoBehaviour
    {
        //TestyTest   
    }
}

Here’s an example of how the project structure could look like:

18 Likes

@Paalo Looks like ProjectWindowUtil.CreateScriptAssetFromTemplateFile does not exist in Unity 2018.3 what version was that method introduced in?