मैं स्वचालित रूप से जेनरेट की गई स्क्रिप्ट को कैसे अनुकूलित करूं?


11

जब आप एकता संपादक के माध्यम से एक स्क्रिप्ट बनाते हैं, तो यह कुछ पूर्व-स्वरूपित कोड के साथ एक स्क्रिप्ट उत्पन्न करता है।

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

    }
}

जब मैं एक स्क्रिप्ट बनाता हूं, तो मुझे आमतौर पर अतिरिक्त कोड का उपयोग करने की गारंटी दी जाती है, जैसे नाम या कस्टम संपादक। इसके अलावा, मैं लगभग हमेशा स्वचालित रूप से उत्पन्न स्क्रिप्ट से सामग्री हटाता हूं । क्या एकता द्वारा उत्पन्न स्वचालित कोड को बदलने का कोई तरीका है?


1
मैंने ऐसा करने के बारे में कभी सोचा भी नहीं था। पूछने के लिए धन्यवाद! अब दो उत्तरों को जोड़ने के लिए एक टेम्प्लेट है और फिर इसे अतिरिक्त जानकारी डालने के लिए पार्स करें, जैसे नामस्थान ...
Draco18s अब SE

जवाबों:


4

इसके अलावा आप भी कर सकते हैं

  1. एसेट्स / एडिटर फ़ोल्डर में एक संपादक स्क्रिप्ट जोड़ें जो सब्सक्राइब करता है OnWillCreateAssetकि आप आउटपुट को पार्स कर सकते हैं और इसे संशोधित कर सकते हैं। उदाहरण लिपि के लिए जो स्वचालित रूप से नामस्थान सम्मिलित करेगी, वह निम्नलिखित की तरह दिख सकती है:

    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. OnWillCreateAssetजैसे आसान रिप्लेसमेंट के लिए टेम्प्लेट में खुद के कंट्रोल सीक्वेंस डालें

    finalCode = finalCode.Replace(@"#date#", DateTime.Now);
  3. टेम्पलेट फ़ोल्डर में अधिक टेम्पलेट जोड़ें, उदाहरण के लिए सिंगलटन पैटर्न के लिए - एकता एकल स्क्रिप्ट टेम्पलेट तक सीमित नहीं है।

  4. विज़ुअल स्टूडियो कोड स्निपेट नई स्क्रिप्ट बनाने का तरीका कस्टमाइज़ करने का तरीका है ... (और आगे भी - नई स्क्रिप्ट पार्ट्स)। उदाहरण के लिए, निजी के लिए एक कोड स्निपेट SerializeFieldकाम में आ सकता है। आयात करने के बाद 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>
    

    करने के लिए उपकरण / कोड स्निपेट प्रबंधक / मेरे कोड स्निपेट्स आप बस डबल टैब "पीएफ" टाइप कर सकते हैं और क्षेत्र का नाम लिखें। उदाहरण के लिए:

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

    अधिक सुविधाजनक भी अक्सर लंबे अनुक्रमों को दोहराया जाएगा, उदाहरण के लिए SerializeFieldफ़ील्ड द्वारा समर्थित संपत्ति ।

  5. विज़ुअल स्टूडियो बहुत शक्तिशाली कोड जनरेशन टूल भी प्रदान करता है, T4 टेक्स्ट टेम्प्लेट्स (EF T4 का उपयोग कर रहा है), हालाँकि मुझे व्यक्तिगत रूप से एकता परियोजनाओं के लिए व्यावहारिक उपयोग संदिग्ध लगता है - वे ओवरकिल हैं, काफी जटिल हैं और प्रोजेक्ट का संकलन संभवतः विज़ुअल व्यू पर निर्भर है स्टूडियो।


यह एक आकर्षण की तरह काम किया है! मैंने भविष्य के उपयोगकर्ताओं के लिए प्रासंगिक नामस्थान जोड़े हैं। मुझे एक और समस्या भी थी, हालाँकि मुझे लगता है कि यह मेरे लिए एक अनोखी बात हो सकती है; मैं उपयोग नहीं कर सकता Path.GetFileWithoutExtension। यह मुझे बताता है कि यह एक का उपयोग करने की कोशिश कर रहा है MonoBehaviour, जो अजीब लगता है। मैं नामस्थान शामिल करता हूं using Path = System.IO.Path.GetFileWithoutExtension, और मैं Pathसभी को एक साथ खो देता हूं । अंत में, मुझे पूरी तरह से लाइन को फेकना पड़ा, खुद ( .Contains("class " + System.IO.Path.GetFileNameWithoutExtension(assetPath)));)।
Gnemlock

BRL के साथ CRLF और UTF-8 के बजाय LF और UTF-8 के साथ फ़ाइलें सुनिश्चित करने का सबसे सरल तरीका क्या है?
एरोन फ्रेंके

@AaronFranke अच्छी तरह से ... बल्कि विशिष्ट अनुरोध। मैं stackoverflow.com पर यह पूछने की कोशिश करूँगा कि कैसे BF के साथ केवल LF string/ File.Writeआउटपुट बनाया जा सकता है। जहाँ तक मुझे पता है कि 'n' सिर्फ LF होना चाहिए , तो आप Environment.Newlineइसके बजाय कोशिश भी कर सकते हैं लेकिन यह CRLF होना चाहिए। यदि सब कुछ विफल रहता है तो गिट हुक का उपयोग करने का विकल्प भी हो सकता है। बीओएम इस स्टैकओवरफ्लो प्रश्न के साथ आसान होना चाहिए ।
वंद्रा

15

आप अपने एकता स्थापना फ़ोल्डर में स्वचालित रूप से कोड उत्पन्न करने के लिए स्क्रिप्ट टेम्पलेट पा सकते हैं। मुझे "एकता / संपादक / डेटा / संसाधन / ScriptTemplates" के तहत टेम्पलेट मिलते हैं , जबकि अन्य स्रोतों ने इसे "एकता / संपादक / डेटा / संसाधन" के तहत पाया है ।

सामान्य UnityScript और C # टेम्प्लेट को क्रमशः "82-Javascript-NewBehaviourScript.js.txt" और "81-C # Script-NewBehaviourScript.cs.txt" फाइलों के रूप में पहचाना जाता है। यूनिटी ऑटो स्क्रिप्ट बनाने के तरीके को बदलने के लिए आप इन फ़ाइलों को सीधे संपादित कर सकते हैं।

आप अतिरिक्त टेम्पलेट भी शामिल कर सकते हैं, जो "प्रोजेक्ट" विंडो से "क्रिएट" का चयन करने पर दिखाई देगा । टेम्पलेट को अद्वितीय नंबरिंग की आवश्यकता नहीं दिखाई देती है, और मेनू पदानुक्रम निर्धारित करने के लिए प्रारंभिक स्ट्रिंग का उपयोग करें, जहां "__" एक सबमेनू को दर्शाता है। उदाहरण के लिए, "81-C # Script__Editor Script-NewBehaviourScript.cs.txt" नाम की फाइल रखने से आपको एक अतिरिक्त " C # स्क्रिप्ट" मेनू मिलेगा , इस टेम्पलेट का उपयोग करके "एडिटर स्क्रिप्ट" बनाने का उप विकल्प होगा ।

करो नहीं मूल टेम्पलेट्स का नाम बदलने; इनका उपयोग सीधे इंजन द्वारा किया जाता है। उदाहरण के लिए, "81-C # Script-NewBehaviourScript.cs.txt" का नाम बदलने से आपको नए C # स्क्रिप्ट को घटकों के रूप में, सीधे निरीक्षक के माध्यम से जोड़ने से रोका जा सकेगा


नीचे मेरा अपना उदाहरण है, हालांकि यह विशेष प्रथाओं को प्रदर्शित करता है जो मैं सबसे अधिक कस्टम हूं। उदाहरण के लिए, मैं अपनी कस्टम एडिटर स्क्रिप्ट को लक्ष्य वर्ग के समान फ़ाइल में रखना पसंद करता हूं, इसलिए मैं #if UNITY_EDITOR .. #endifइसे एक जेनेरिक "बिल्ड न करें" एडिटर फ़ोल्डर में रखने के बजाय इसे इनकैप्सुलेट करता हूं ।

मुझे यकीन नहीं है कि क्या कस्टम नाम स्थान का संदर्भ प्रदान करना संभव है; मैं बस "NAMESPACE" का उपयोग करता हूं, क्योंकि यह मुझे सामान्य रूप से इनबिल्ट "find..replace all" फ़ंक्शन का उपयोग करके सही नाम स्थान-निर्माण प्रदान करने की अनुमति देता है।


नमूना:

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

उत्पादन:

/* 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
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.