Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

How to create your own C# Script Template?

Discussion in 'Scripting' started by elmar1028, Mar 8, 2017.

  1. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,319
    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! :)
     
  2. AndyGainey

    AndyGainey

    Joined:
    Dec 2, 2015
    Posts:
    216
    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:
    Code (CSharp):
    1. Selection.activeObject = asset;
    2. EditorApplication.delayCall += () => { EditorUtility.FocusProjectWindow(); };
    3.  
    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.
     
    Arsonistic and Smarre like this.
  3. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    6,675
  4. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,319
    @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.
     
  5. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    16,222
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    7,352
    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:
    Code (csharp):
    1.  
    2. using UnityEditor;
    3.  
    4. using System.IO;
    5.  
    6. public class CustomMenuEntries
    7. {
    8.     public const string PATH_TO_MYSCRIPT_TEMPLATE = @"D:\zTemp\Template.cs";
    9.  
    10.     [MenuItem("Assets/Create My Custom C# Script")]
    11.     public static void CreateCustomScript(MenuCommand cmd)
    12.     {
    13.         if (Selection.activeObject == null);
    14.         var path = AssetDatabase.GetAssetPath(Selection.activeObject);
    15.         if (File.Exists(path))
    16.             path = Path.GetDirectoryName(path);
    17.         if (string.IsNullOrEmpty(path)) path = "Assets/";
    18.  
    19.  
    20.         File.Copy(PATH_TO_MYSCRIPT_TEMPLATE, Path.Combine(path, "NewScript.cs"));
    21.         AssetDatabase.Refresh();
    22.  
    23.     }
    24. }
    25.  
     
    LouisHong, Ryiah and elmar1028 like this.
  7. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,319
    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: http://answers.unity3d.com/questions/12599/editor-script-need-to-create-class-script-automati.html

    Thanks for helping me everyone :)
     
    LaneFox and Ryiah like this.
  8. GregMeach

    GregMeach

    Joined:
    Dec 5, 2012
    Posts:
    249
    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
    ModifiedCreate.png
    TemplateFolder.png
     
    Last edited: Mar 9, 2017
    angrypenguin likes this.
  9. johnsoncodehk

    johnsoncodehk

    Joined:
    Feb 19, 2016
    Posts:
    12
    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:
    Https://gist.github.com/johnsoncodehk/03d3871a1453d795162a6dbf01f904c3
     
  10. Doug_B

    Doug_B

    Joined:
    Jun 4, 2017
    Posts:
    1,596
    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
    <tab> <tab> and then tab around the replacements (var, item and collection).
     
  11. ShawnFeatherly

    ShawnFeatherly

    Joined:
    Feb 22, 2013
    Posts:
    45
    @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:

    Code (CSharp):
    1.     private static MethodInfo createScriptMethod = typeof(ProjectWindowUtil)
    2.         .GetMethod("CreateScriptAsset", BindingFlags.Static | BindingFlags.NonPublic);
    3.  
    4.     static void CreateScriptAsset(string templatePath, string destName) {
    5.       createScriptMethod.Invoke(null, new object[] { templatePath, destName });
    6.     }
     
    Last edited: Jun 21, 2018
    johnsoncodehk likes this.
  12. ShawnFeatherly

    ShawnFeatherly

    Joined:
    Feb 22, 2013
    Posts:
    45
    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"
     
  13. jura_z

    jura_z

    Unity Technologies

    Joined:
    Oct 10, 2016
    Posts:
    25
    1) Create Assets/ScriptTemplates to override built-in templates on a per-project basis.
    2) Reopen the project
     
    Editali, nih_, nirvanajie and 3 others like this.
  14. APSchmidt

    APSchmidt

    Joined:
    Aug 8, 2016
    Posts:
    3,829
    angrypenguin likes this.
  15. tbriley

    tbriley

    Joined:
    Sep 10, 2013
    Posts:
    114
    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!
     
  16. johnsoncodehk

    johnsoncodehk

    Joined:
    Feb 19, 2016
    Posts:
    12
    Last edited: Jan 16, 2020
    tbriley likes this.
  17. tbriley

    tbriley

    Joined:
    Sep 10, 2013
    Posts:
    114
  18. Sylon87

    Sylon87

    Joined:
    Aug 20, 2018
    Posts:
    196
    hello, i'm trying to create iruntime.. how i should be able to create my script by template then add it to an object?
     
    Last edited: Jan 7, 2020
  19. Paalo

    Paalo

    Joined:
    Jan 20, 2016
    Posts:
    8
    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:
    Code (CSharp):
    1. //ATTENTION: Put this script file into an "Editor"-folder for it to work properly.
    2.  
    3. using UnityEditor;
    4.  
    5. public class CreateNewScriptClassFromCustomTemplate
    6. {
    7.     private const string pathToYourScriptTemplate = "Assets/YourScriptTemplatesFolder/YourTemplateScript.cs.txt";
    8.  
    9.     [MenuItem(itemName: "Assets/Create/Create New Script from Custom Template", isValidateFunction: false, priority: 51)]
    10.     public static void CreateScriptFromTemplate()
    11.     {
    12.         ProjectWindowUtil.CreateScriptAssetFromTemplateFile(pathToYourScriptTemplate, "YourDefaultNewScriptName.cs");
    13.     }
    14. }
    -----

    And "YourTemplateScript.cs.txt" should look something like this:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. namespace YourNamespace
    6. {
    7.     public class #SCRIPTNAME# : MonoBehaviour
    8.     {
    9.         //TestyTest  
    10.     }
    11. }
    Here's an example of how the project structure could look like: upload_2020-1-13_15-7-8.png
     
  20. aFeesh

    aFeesh

    Joined:
    Feb 12, 2015
    Posts:
    28
    @Paalo Looks like ProjectWindowUtil.CreateScriptAssetFromTemplateFile does not exist in Unity 2018.3 what version was that method introduced in?
     
  21. elmar1028

    elmar1028

    Joined:
    Nov 21, 2013
    Posts:
    2,319
  22. johnsoncodehk

    johnsoncodehk

    Joined:
    Feb 19, 2016
    Posts:
    12
  23. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,052
    I love Paalo's solution.

    For those of us with multiple editors installed (anyone making asset store assets, for instance), I also recommend using symlinks, which seamlessly forces Unity to share the templates across all versions of Unity installed.

    (I cannot think of a single situation where I'd need different copies of Unity to have their own unique project templates, so I think Unity's decision to bundle them inside the Editor's binary/install folder was less than ideal).

    For windows: You need a HARD symlink (as Windows isn't as good an OS when it comes to understanding symlinks, you need to be more brutal). First move the ScriptTemplates folder somewhere on your hard disk, then delete it from all current Editors, and instead use "mklink /J [location of shared folder] [location of Unity editor's template folder]" once for each Editor.

    e.g.
    Code (CSharp):
    1. mklink /J Unity-2019.3.3\Editor\Data\Resources\ScriptTemplates D:\development\Unity-shared-ScriptTemplates
    Similarly with OSX, but instead of mklink, you're fine to use a SOFT symlink (OSX has a more standard Unix-like implementation of symlinks, and apps should all be happy to use the softlinked folder) - use "ln -s [location of shared folder] [location of unity editor tempaltes folder]"
     
  24. TDVDev

    TDVDev

    Joined:
    Mar 25, 2020
    Posts:
    2
unityunity