Làm cách nào để tùy chỉnh tập lệnh được tạo tự động?


11

Khi bạn tạo tập lệnh thông qua trình soạn thảo Unity, nó sẽ tạo tập lệnh với một số mã được định dạng trước.

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

    }
}

Khi tôi tạo tập lệnh, tôi thường được đảm bảo sử dụng mã bổ sung, chẳng hạn như không gian tên hoặc trình chỉnh sửa tùy chỉnh. Hơn nữa, tôi hầu như luôn xóa nội dung khỏi tập lệnh được tạo tự động. Có cách nào để thay đổi mã tự động do Unity tạo ra không?


1
Tôi thậm chí không bao giờ nghĩ về việc làm này. Cam ơn vi đa hỏi! Bây giờ để kết hợp hai câu trả lời để có một mẫu sau đó phân tích nó để chèn thêm thông tin, như không gian tên ...
Draco18 không còn tin tưởng SE

Câu trả lời:


4

Ngoài ra bạn cũng có thể

  1. Thêm một tập lệnh biên tập trong thư mục Tài sản / Trình OnWillCreateAssetchỉnh sửa đăng ký vào nơi bạn có thể phân tích cú pháp đầu ra và sửa đổi nó. Ví dụ tập lệnh sẽ tự động chèn không gian tên có thể trông như sau:

    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. Chèn các chuỗi điều khiển riêng vào các mẫu để dễ dàng thay thế OnWillCreateAsset, ví dụ:

    finalCode = finalCode.Replace(@"#date#", DateTime.Now);
  3. Thêm nhiều mẫu vào thư mục mẫu, ví dụ một mẫu cho mẫu Singleton - Unity không giới hạn ở mẫu tập lệnh đơn.

  4. Các đoạn mã phòng thu trực quan là cách để tùy chỉnh tạo tập lệnh mới (... và thậm chí xa hơn - các phần tập lệnh mới). Ví dụ: một đoạn mã cho riêng tư SerializeFieldcó thể có ích. Sau khi nhập 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>

    vào Công cụ / Trình quản lý đoạn mã / Đoạn mã của tôi, bạn có thể chỉ cần nhập tab đôi "pf" và nhập tên của trường. Ví dụ:

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

    Thậm chí thuận tiện hơn sẽ là các đoạn trích cho các chuỗi dài hơn lặp đi lặp lại, ví dụ như thuộc tính chỉ đọc được hỗ trợ bởi SerializeFieldtrường.

  5. Visual studio cũng cung cấp công cụ tạo mã rất mạnh, Mẫu văn bản T4 (EF đang sử dụng T4), mặc dù cá nhân tôi thấy việc sử dụng thực tế cho các dự án Unity đáng nghi ngờ - chúng quá mức, khá phức tạp và việc biên dịch dự án có thể sẽ phụ thuộc vào Visual Xưởng.


Điều này đã làm việc như một nét duyên dáng! Tôi đã thêm các không gian tên có liên quan cho người dùng trong tương lai. Tôi cũng có một vấn đề nữa, mặc dù tôi nghĩ nó có thể là một vấn đề duy nhất đối với tôi; Tôi không thể sử dụng Path.GetFileWithoutExtension. Nó cho tôi biết nó đang cố gắng truy cập a MonoBehaviour, có vẻ kỳ quặc. Tôi bao gồm không gian tên using Path = System.IO.Path.GetFileWithoutExtensionvà tôi mất Pathtất cả cùng nhau. Cuối cùng, tôi đã phải tự mình hoàn thành dòng ( .Contains("class " + System.IO.Path.GetFileNameWithoutExtension(assetPath)));).
Gnemlock

Cách đơn giản nhất để đảm bảo các tệp được tạo bằng LF và UTF-8 thay vì CRLF và UTF-8 với BOM?
Aaron Franke

@AaronFranke tốt ... đó là yêu cầu khá cụ thể. Tôi sẽ thử hỏi trên stackoverflow.com cách tạo string/ File.Writexuất ra chỉ với BOM. Theo như tôi biết '\ n' chỉ nên là LF, bạn cũng có thể thử Environment.Newlinethay thế nhưng nó phải là CRLF. Cũng có thể có một tùy chọn để sử dụng git hook nếu mọi thứ khác không thành công. BOM nên dễ dàng với câu hỏi stackoverflow này .
wonderra

15

Bạn có thể tìm thấy các mẫu tập lệnh để tự động tạo mã trong thư mục cài đặt Unity của mình. Tôi tìm thấy các mẫu trong "Unity / Editor / Data / Resources / ScriptTemsheet" , trong khi các nguồn khác đã tìm thấy nó trong "Unity / Editor / Data / Resources" .

Các mẫu UnityScript và C # chung được xác định lần lượt là các tệp "82-Javascript-NewBehaviourScript.js.txt""81-C # Script-NewBehaviourScript.cs.txt" . Bạn có thể trực tiếp chỉnh sửa các tệp này để thay đổi cách Unity tự động tạo tập lệnh.

Bạn cũng có thể bao gồm các mẫu bổ sung, sẽ xuất hiện khi bạn chọn "Tạo" từ cửa sổ "Dự án" . Mẫu không xuất hiện để yêu cầu đánh số độc đáo, và sử dụng chuỗi ban đầu để xác định thứ bậc đơn, trong đó "__" biểu thị một menu con. Ví dụ: có một tệp có tên "81-C # Script__Editor Script-NewBehaviourScript.cs.txt" sẽ cung cấp cho bạn một menu "Tập lệnh C # " bổ sung , với tùy chọn phụ để tạo "Tập lệnh biên tập" bằng mẫu này.

Đừng không đổi tên các mẫu ban đầu; những cái này được sử dụng trực tiếp hơn, bởi động cơ. Ví dụ: đổi tên "81-C # Script-NewBehaviourScript.cs.txt" sẽ ngăn bạn thêm các tập lệnh C # mới làm thành phần, trực tiếp thông qua trình kiểm tra.


Dưới đây là ví dụ của riêng tôi, mặc dù nó cho thấy các thực tiễn cụ thể mà tôi tùy chỉnh nhất. Ví dụ, tôi thích có tập lệnh biên tập tùy chỉnh của mình trong cùng một tệp với lớp đích, vì vậy tôi gói nó vào #if UNITY_EDITOR .. #endif, thay vì đặt nó vào thư mục trình soạn thảo "không biên dịch trong bản dựng" chung chung.

Tôi không chắc liệu thậm chí có thể cung cấp bối cảnh của một không gian tên tùy chỉnh hay không; Tôi chỉ đơn giản sử dụng "NnamPACE", vì điều này cho phép tôi cung cấp chính xác việc tạo hậu kỳ không gian tên, sử dụng chức năng "find..replace all" thường được xây dựng.


Bản mẫu:

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

Đầu ra:

/* 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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.