Comment personnaliser un script généré automatiquement?

11

Lorsque vous créez un script via l'éditeur Unity, il génère un script avec du code pré-formaté.

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

public class GenericClass : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

Lorsque je crée un script, je suis généralement assuré d'utiliser du code supplémentaire, tel qu'un espace de noms ou un éditeur personnalisé. De plus, je supprime presque toujours le contenu du script généré automatiquement. Existe-t-il un moyen de modifier le code automatique généré par Unity?

Gnemlock
la source
1
Je n'ai même jamais pensé à faire ça. Merci d'avoir posé la question! Maintenant, pour combiner les deux réponses pour avoir un modèle , puis l'analyser pour insérer des informations supplémentaires, comme l'espace de noms ...
Draco18s ne fait plus confiance au SE

Réponses:

4

De plus, vous pouvez également

  1. Ajoutez un script d'éditeur dans le dossier Assets / Editor qui s'abonne à l' OnWillCreateAssetendroit où vous pouvez analyser la sortie et la modifier. Par exemple, un script qui insérerait automatiquement un espace de noms pourrait ressembler à ceci:

    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text.RegularExpressions;
    
    using UnityEditor;
    
    public class InsertNS : UnityEditor.AssetModificationProcessor
    {
        public static void OnWillCreateAsset(string path)
        {
            string assetPath = Regex.Replace(path, @".meta$", string.Empty);
            if (!assetPath.EndsWith(".cs")) return;
    
            var code = File.ReadAllLines(assetPath).ToList();
            if (code.Any(line => line.Contains("namespace"))) return;//already added by IDE
    
            //insert namespace
            int idx = code.FindIndex(line => line
                .Contains("class " + Path.GetFileNameWithoutExtension(assetPath)));
            code.Insert(idx, Regex.Replace(
            assetPath.Replace('/','.'), @"^([\w+.]+)\.\w+\.cs$", "namespace $1 {\n"));
            code.Add("}");
    
            //correct indentation
            for (int i = idx + 1; i < code.Count - 1; i++) code[i] = '\t' + code[i];
    
            var finalCode = string.Join("\n", code.ToArray());
            File.WriteAllText(assetPath, finalCode);
            AssetDatabase.Refresh();
        }
    }
  2. Insérez vos propres séquences de contrôle dans les modèles pour les remplacer facilement OnWillCreateAsset, par exemple

    finalCode = finalCode.Replace(@"#date#", DateTime.Now);
  3. Ajoutez plus de modèles au dossier de modèles, par exemple un pour le modèle Singleton - Unity n'est pas limité à un seul modèle de script.

  4. Les extraits de code de Visual Studio sont un moyen de personnaliser la création de nouveaux scripts (... et encore plus - de nouvelles parties de script). Par exemple, un extrait de code privé SerializeFieldpeut être utile. Après l'importation privateField.snippet:

    <?xml version="1.0" encoding="utf-8"?>
    <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
      <CodeSnippet Format="1.0.0">
        <Header>
          <Title>
            Serialized private field
          </Title>
          <Author>Myself</Author>
          <Description>Adds private serializable field visible to Unity editor</Description>
          <Shortcut>pf</Shortcut>
        </Header>
        <Snippet>
          <Imports>
            <Import>
              <Namespace>UnityEngine</Namespace>
            </Import>
          </Imports>
          <Declarations>
            <Literal>
              <ID>FieldName</ID>
              <ToolTip>Replace with field name.</ToolTip>
              <Default>myField</Default>
            </Literal>
          </Declarations>
          <Code Language="CSharp">
            <![CDATA[[SerializeField] float _$FieldName$;]]>
          </Code>
        </Snippet>
      </CodeSnippet>
    </CodeSnippets>

    dans Outils / Gestionnaire d'extraits de code / Mes extraits de code, vous pouvez simplement taper le double onglet "pf" et saisir le nom du champ. Par exemple:

    //"pf" tab tab "speed" produces
    [SerializeField] float _speed;

    Des extraits de code pour des séquences plus longues souvent répétées, par exemple une propriété en lecture seule appuyée par un SerializeFieldchamp, seraient encore plus pratiques .

  5. Visual studio propose également un outil de génération de code très puissant, les modèles de texte T4 (EF utilise T4), bien que je trouve personnellement l'utilisation pratique des projets Unity douteuse - ils sont exagérés, assez compliqués et la compilation du projet dépendra probablement de Visual Studio.

Wondra
la source
Cela a fonctionné comme un charme! J'ai ajouté des espaces de noms pertinents pour les futurs utilisateurs. J'ai également eu un autre problème, bien que je pense qu'il pourrait être unique pour moi; Je ne peux pas utiliser Path.GetFileWithoutExtension. Il me dit qu'il tente d'accéder à un MonoBehaviour, ce qui semble étrange. J'inclus l'espace de noms using Path = System.IO.Path.GetFileWithoutExtensionet je perds Pathtous ensemble. Au final, j'ai dû franchir complètement la ligne, elle-même ( .Contains("class " + System.IO.Path.GetFileNameWithoutExtension(assetPath)));).
Gnemlock
Quelle est la manière la plus simple de s'assurer que les fichiers sont créés avec LF et UTF-8 plutôt qu'avec CRLF et UTF-8 avec BOM?
Aaron Franke
@AaronFranke bien ... c'est une demande plutôt spécifique. J'essaierais de demander sur stackoverflow.com comment faire string/ File.Writeproduire LF uniquement avec BOM. Pour autant que je sache, '\ n' devrait être juste LF, vous pouvez également essayer à la Environment.Newlineplace, mais ce devrait être CRLF. Il peut également y avoir une option pour utiliser les hooks git si tout le reste échoue. La nomenclature devrait être facile avec cette question de stackoverflow .
wondra
15

Vous pouvez trouver les modèles de script pour générer automatiquement du code dans votre dossier d'installation Unity. Je trouve les modèles sous "Unity / Editor / Data / Resources / ScriptTemplates" , tandis que d' autres sources l' ont trouvé sous "Unity / Editor / Data / Resources" .

Les modèles UnityScript et C # génériques sont identifiés comme étant les fichiers "82-Javascript-NewBehaviourScript.js.txt" et "81-C # Script-NewBehaviourScript.cs.txt" , respectivement. Vous pouvez modifier directement ces fichiers pour changer la façon dont Unity génère automatiquement le script.

Vous pouvez également inclure des modèles supplémentaires, qui apparaîtront lorsque vous sélectionnez "Créer" dans la fenêtre "Projet" . Les modèles ne semblent pas nécessiter une numérotation unique et utilisent la chaîne initiale pour déterminer la hiérarchie du menu, où «__» désigne un sous-menu. Par exemple, avoir un fichier nommé "81-C # Script__Editor Script-NewBehaviourScript.cs.txt" vous donnera un menu supplémentaire " C # Script" , avec l'option secondaire pour créer un "Script d'édition" en utilisant ce modèle.

Ne renommez pas les modèles d'origine; ceux-ci sont utilisés plus directement par le moteur. Par exemple, renommer "81-C # Script-NewBehaviourScript.cs.txt" vous empêchera d'ajouter de nouveaux scripts C # en tant que composants, directement via l'inspecteur.


Voici mon propre exemple, bien qu'il montre des pratiques particulières auxquelles je suis le plus habitué. Par exemple, je préfère avoir mon script d'éditeur personnalisé dans le même fichier que la classe cible, donc je l'encapsule dans #if UNITY_EDITOR .. #endif, au lieu de le placer dans un dossier d'éditeur générique "ne pas compiler dans la construction".

Je ne sais pas s'il est même possible de fournir le contexte d'un espace de noms personnalisé; J'utilise simplement "NAMESPACE", car cela me permet de fournir le bon espace de noms après la création, en utilisant la fonction "find..replace all" généralement intégrée.


Le gabarit:

/* Created by Gnemlock */

using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace NAMESPACE
{
    public class #SCRIPTNAME# : MonoBehaviour 
    {
        /// <summary>This method will be called at the start of each frame where this 
        /// instance of <see cref="NAMESPACE.#SCRIPTNAME#"/> is enabled.</summary>
        void Update ()
        {
            #NOTRIM#
        }
    }
}

namespace NAMESPACE.UTILITY
{
    #if UNITY_EDITOR
    [CustomEditor(typeof(#SCRIPTNAME#))] public class #SCRIPTNAME#Editor : Editor
    {
        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();

            #SCRIPTNAME# s#SCRIPTNAME# = target as #SCRIPTNAME#;
        }
    }
    #endif
}

Le résultat:

/* Created by Gnemlock */

using UnityEngine;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace MyNamespace
{

    public class UpdatedClass : MonoBehaviour 
    {
        /// <summary>This method will be called at the start of each frame where this 
        /// instance of <see cref="MyNamespace.UpdatedClass"/> is enabled.</summary>
        void Update ()
        {

        }
    }
}

namespace MyNamespace.UTILITY
{
    #if UNITY_EDITOR
    [CustomEditor(typeof(UpdatedClass))] public class UpdatedClassEditor : Editor
    {
        public override void OnInspectorGUI()
        {
            DrawDefaultInspector();

            UpdatedClass sUpdatedClass = target as UpdatedClass;
        }
    }
    #endif
}
Gnemlock
la source