Come personalizzo lo script generato automaticamente?


11

Quando si crea uno script tramite l'editor Unity, genera uno script con un codice pre-formattato.

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 () {

    }
}

Quando creo uno script, in genere mi viene garantito l'utilizzo di codice aggiuntivo, come uno spazio dei nomi o un editor personalizzato. Inoltre, elimino quasi sempre il contenuto dallo script generato automaticamente. C'è un modo per cambiare il codice automatico generato da Unity?


1
Non ho nemmeno pensato di farlo. Grazie per avermelo chiesto! Ora per combinare le due risposte per avere un modello e quindi analizzarlo per inserire informazioni aggiuntive, come lo spazio dei nomi ...
Draco18s non si fida più del

Risposte:


4

Inoltre puoi anche

  1. Aggiungi uno script dell'editor nella cartella Risorse / Editor che si abbona a OnWillCreateAssetdove è possibile analizzare l'output e modificarlo. Ad esempio, uno script che inserirà automaticamente lo spazio dei nomi potrebbe apparire come segue:

    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. Inserisci le tue sequenze di controllo nei modelli per sostituirle facilmente OnWillCreateAsset, ad es

    finalCode = finalCode.Replace(@"#date#", DateTime.Now);
  3. Aggiungi altri modelli alla cartella dei modelli, ad esempio uno per il modello Singleton - Unity non è limitato al modello di script singolo.

  4. I frammenti di codice di Visual Studio sono un modo per personalizzare la creazione di nuovi script (... e anche di più - nuove parti di script). Ad esempio, uno snippet di codice per privati SerializeFieldpotrebbe tornare utile. Dopo l'importazione 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>
    

    a Strumenti / Gestore frammenti di codice / Frammenti di codice personali puoi semplicemente digitare la doppia scheda "pf" e digitare il nome del campo. Per esempio:

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

    Ancora più convenienti sarebbero gli snippet per sequenze più lunghe spesso ripetute, ad esempio proprietà di sola lettura supportate dal SerializeFieldcampo.

  5. Visual Studio offre anche uno strumento di generazione di codice molto potente, i modelli di testo T4 (EF sta usando T4), anche se personalmente trovo dubbioso l'uso pratico dei progetti Unity: sono eccessivi, abbastanza complicati e la compilazione del progetto probabilmente dipenderà da Visual Studio.


Questo ha funzionato come un fascino! Ho aggiunto spazi dei nomi pertinenti per i futuri utenti. Ho anche avuto un altro problema, anche se penso che potrebbe essere unico per me; Non posso usare Path.GetFileWithoutExtension. Mi dice che sta provando ad accedere a MonoBehaviour, il che sembra strano. Includo lo spazio dei nomi using Path = System.IO.Path.GetFileWithoutExtensione perdo Pathtutti insieme. Alla fine, ho dovuto abbandonare completamente la linea stessa ( .Contains("class " + System.IO.Path.GetFileNameWithoutExtension(assetPath)));).
Gnemlock,

Qual è il modo più semplice per garantire che i file vengano creati con LF e UTF-8 anziché CRLF e UTF-8 con BOM?
Aaron Franke,

@AaronFranke bene ... questa è una richiesta piuttosto specifica. Proverei a chiedere a stackoverflow.com come creare string/ File.Writeprodurre LF-only con BOM. Per quanto ne so '\ n' dovrebbe essere solo LF, puoi anche provare Environment.Newlineinvece, ma dovrebbe essere CRLF. Potrebbe anche esserci un'opzione per usare git hook se tutto il resto fallisce. La distinta componenti dovrebbe essere semplice con questa domanda StackOverflow .
Wondra,

15

È possibile trovare i modelli di script per la generazione automatica del codice nella cartella di installazione di Unity. Trovo i modelli in "Unity / Editor / Data / Resources / ScriptTemplates" , mentre altre fonti lo hanno trovato in "Unity / Editor / Data / Resources" .

I modelli UnityScript e C # generici sono identificati rispettivamente come file "82-Javascript-NewBehaviourScript.js.txt" e "81-C # Script-NewBehaviourScript.cs.txt" . È possibile modificare direttamente questi file per cambiare il modo in cui Unity genera automaticamente lo script.

Puoi anche includere modelli aggiuntivi, che appariranno quando selezioni "Crea" dalla finestra "Progetto" . I modelli non sembrano richiedere una numerazione univoca e utilizzano la stringa iniziale per determinare la gerarchia dei menu, dove "__" indica un sottomenu. Ad esempio, avere un file chiamato "81-C # Script__Editor Script-NewBehaviourScript.cs.txt" ti darà un ulteriore menu "Script C #" , con l'opzione secondaria per creare uno "Script Editor" usando questo modello.

Evitare Non rinominare i modelli originali; questi sono usati più direttamente dal motore. Ad esempio, rinominare "81-C # Script-NewBehaviourScript.cs.txt" ti impedirà di aggiungere nuovi script C # come componenti, direttamente tramite la finestra di ispezione.


Di seguito è riportato il mio esempio, anche se dimostra pratiche particolari a cui sono maggiormente abituato. Ad esempio, preferisco avere il mio script dell'editor personalizzato nello stesso file della classe di destinazione, quindi lo incapsulo in #if UNITY_EDITOR .. #endif, invece di inserirlo in una cartella dell'editor generica "non compilare in build".

Non sono sicuro se sia persino possibile fornire il contesto di uno spazio dei nomi personalizzato; Uso semplicemente "NAMESPACE", in quanto ciò mi consente di fornire la corretta post-creazione dello spazio dei nomi, utilizzando la funzione "trova..replace all" incorporata comunemente.


Il template:

/* 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
}

Il risultato:

/* 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
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.