自動生成されたスクリプトをカスタマイズするにはどうすればよいですか?


11

Unityエディターを介してスクリプトを作成すると、事前にフォーマットされたコードを含むスクリプトが生成されます。

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

    }
}

スクリプトを作成すると、通常、名前空間やカスタムエディターなどの追加コードを使用することが保証されます。さらに、ほとんどの場合、自動生成されたスクリプトからコンテンツを削除します。Unityによって生成された自動コードを変更する方法はありますか?


1
私もこれをすることを考えたことはありません。質問してくれてありがとう!今すぐテンプレートを持っている2つの答えを組み合わせること、名前空間のように、余分な情報を挿入するために、それを解析し...
Draco18sもはや信託SE

回答:


4

さらに、あなたもすることができます

  1. Assets / Editorフォルダーにエディタースクリプトを追加して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. テンプレートフォルダーにテンプレートをさらに追加します。たとえば、シングルトンパターンのテンプレートを追加します-Unityは単一のスクリプトテンプレートに限定されません。

  4. Visual Studioのコードスニペットは、新しいスクリプトの作成をカスタマイズする方法です(...さらには-新しいスクリプトパーツ)。たとえば、privateのコードスニペット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」と入力し、フィールドの名前を入力することができます。例えば:

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

    さらに便利なのは、頻繁に繰り返される長いシーケンスのスニペットですSerializeField。たとえば、フィールドに裏打ちされた読み取り専用プロパティです。

  5. Visual Studioは、非常に強力なコード生成ツールであるT4テキストテンプレート(EFはT4を使用)も提供していますが、Unityプロジェクトの実際の使用は疑わしいと私は思います。スタジオ。


これは魅力のように機能しました!今後のユーザーのために関連する名前空間を追加しました。もう1つ問題がありましたが、それは私に固有の問題かもしれません。使用できませんPath.GetFileWithoutExtension。奇妙に見えるにアクセスしようとしていることがMonoBehaviourわかります。名前空間を含めたためusing Path = System.IO.Path.GetFileWithoutExtensionPathすべてが失われました。結局、私はライン自体を完全に掘り下げる必要がありました(.Contains("class " + System.IO.Path.GetFileNameWithoutExtension(assetPath)));)。
Gnemlock 2017年

BOMでCRLFとUTF-8ではなく、LFとUTF-8でファイルを作成する最も簡単な方法は何ですか?
アーロンフランケ

@AaronFrankeまあ...それはむしろ特定の要求です。私が作る方法stackoverflow.comに尋ねてみますstring/ File.WriteBOMで出力LF-のみ。私が知る限り、「\ n」 LFでなければなりませんが、Environment.Newline代わりに試すこともできますが、CRLFにする必要があります。他のすべてが失敗した場合にgitフックを使用するオプションもあります。BOMは、このスタックオーバーフローの質問で簡単になるはずです。
ワンドラ

15

コードを自動生成するためのスクリプトテンプレートは、Unityインストールフォルダーにあります。テンプレートは「Unity / Editor / Data / Resources / ScriptTemplates」の下にありますが、他のソースで「Unity / Editor / Data / Resources」の下にあります。

一般的なUnityScriptおよびC#テンプレートは、それぞれファイル"82-Javascript-NewBehaviourScript.js.txt"および"81-C#Script-NewBehaviourScript.cs.txt"として識別されます。これらのファイルを直接編集して、Unityがスクリプトを自動生成する方法を変更できます。

「プロジェクト」ウィンドウから「作成」を選択すると表示される追加のテンプレートを含めることもできます。テンプレートは一意の番号付けを必要としないようであり、最初の文字列を使用してメニュー階層を決定します。「__」はサブメニューを示します。たとえば、「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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.