【Unit Editor编辑器】自定义窗口EditorWindow,创建模板脚本工具

总览:

在这里插入图片描述

关键点:

1.创建自定义窗口
2.正则表达式校验输入的脚本名是否符合脚本命名规则
3.获取Project窗口中选中文件夹路径
4.简单的文件操作

原始方法:

原始的创建脚本操作是这样的,Unity中在Project面板中,右键/Create/C# Script,如图:在这里插入图片描述
创建好的脚本其实不是空白,而是已经有了简单的Start和Update方法,每次都是一样的(除了名字是自己修改后的),由此可见新建的脚本中的内容就是从一个模子里刻出来的,而这个模子就在Unity的安装目录下…Unity\Editor\Data\Resources\ScriptTemplates
在这里插入图片描述
打开后是这样的.

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

public class #SCRIPTNAME# : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        #NOTRIM#
    }

    // Update is called once per frame
    void Update()
    {
        #NOTRIM#
    }
}

终于和这个模板见面了,接下将按照同样的思路创建自己的模子,并通过工具创建脚本,而自己的模板就放工程里了,避免污染了原生态…

开始新的方式:

1.创建自定义窗口

新建脚本,比如我这里创建的脚本叫CreateScriptWindow,然后继承至UnityEditor.EditorWindow,创建窗口方法如下:

[MenuItem("Tools/Create Script")]
static void Create()
{
    CreateScriptWindow window = (CreateScriptWindow)GetWindow(typeof(CreateScriptWindow), false, "Create Script", false);
    window.Show(true);
}

MeunItem则是指定一个菜单选项,点击则响应此方法.

public static EditorWindow GetWindow(Type t, bool utility, string title);

t:代表窗口的类型
title:窗口名字,左上角显示的标签
utility:
false表示正常窗口,就是我们在Unity中常见的窗口,可以拖出来也可以和其他窗口合并在一起并产生遮挡.
在这里插入图片描述
true则不能合并,并且一直在上层显示
在这里插入图片描述
窗口创建出来了,接下来向窗口中填充需要的控件元素:
两个可输入的文本:

_scriptName = EditorGUILayout.TextField("脚本名:", _scriptName);
_description = EditorGUILayout.TextField("功能描述(选填):", _description);

一个显示文本:

EditorGUILayout.LabelField("路径:", path);

一个按钮:

if (GUILayout.Button("创建", GUILayout.Height(40))){}

就是本次自定义窗口的所有元素了,接下里就逻辑填充:

2.正则表达式校验输入合法性

既然是输入脚本名,那么不可避免的是对输入合法性的校验,正则表达式则是非常棒的解决方式.
C#中需要先引入命名空间using System.Text.RegularExpressions;
合法的脚本名只能包含字母(大小写),数字和下划线,且只能以字母和下划线开头.
pattern : “^[a-zA-Z_][a-zA-Z0-9_]*$”
^是代表从第一个字符开始匹配,而&则是表示匹配输入字符串的结尾位置
[a-zA-Z_]表示只能是字母或下划线
[a-zA-Z0-9_]*这里的星号表示前面的字符出现次数为0次或多次
更多细节可以参考这里.

//校验脚本名(只能包含数字,字母,下划线且必须以字母或下划线开头)
    bool CheckScriptName(string scriptName)
    {
        Regex regex = new Regex("^[a-zA-Z_][a-zA-Z0-9_]*$");
        return regex.IsMatch(scriptName);
    }

3.输入不合法提示

使用EditorWindow下的ShowNotification(new GUIContent(“请输入正确的脚本名!”));
在这里插入图片描述

4.路径获取

这里获取所选文件夹路径的方式,采用之前写的【Unity Editor编辑器】 代码获取project面板选中资源路径(自定义右键菜单)中的方式。
如果没有选择文件夹,则给出错误提示:在这里插入图片描述

5.生成脚本:

string content = File.ReadAllText(TEMPLATE_PATH);//从模板文件中读取内容
content = content.Replace("MyScript", _scriptName); //替换脚本名
content = content.Replace("time", DateTime.Now.ToString());//替换创建时间
content = content.Replace("ReplaceDescription", _description);//填入脚本功能描述
File.WriteAllText(path, content, Encoding.UTF8);//将修改后的内容写入新的脚本
AssetDatabase.Refresh();//马上刷新,方便在Project中直接看到新生成的脚本
ShowNotification(new GUIContent("Success!"));

附上完整代码:

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using System;
using System.Text.RegularExpressions;

/// <summary>
/// Created by Vitens on 2020/7/25 13:14:55
/// 
/// 创建脚本窗口
/// </summary>
public class CreateScriptWindow : EditorWindow
{
    const string TEMPLATE_PATH = "Assets/Platform/Editor/MyTemplateScript.txt";//模板路径

    [MenuItem("Tools/Create Script")]
    static void Create()
    {
        CreateScriptWindow window = (CreateScriptWindow)GetWindow(typeof(CreateScriptWindow), false, "Create Script");
        window.Show(true);
    }

    string _scriptName;
    string _description;
    void OnGUI()
    {
        //获取选中的文件夹路径
        string selectDirPath = EditorUtils.GetOneSelectFilePath();
        //如果选中的是文件夹,则正常拼接新建脚本路径
        if(Directory.Exists(selectDirPath))
        {
            _scriptName = EditorGUILayout.TextField("脚本名:", _scriptName);
            _description = EditorGUILayout.TextField("功能描述(选填):", _description);
            string path = selectDirPath + "/" + _scriptName + ".cs";
            EditorGUILayout.LabelField("路径:", path);
            EditorGUILayout.Space();
            if (GUILayout.Button("创建", GUILayout.Height(40)))
            {
                //命名规则校验
                if (!CheckScriptName(_scriptName))
                {
                    ShowNotification(new GUIContent("请输入正确的脚本名!"));   
                }
                //查重校验
                else if (CheckRepeat(selectDirPath))
                {
                    ShowNotification(new GUIContent("当前文件夹下已经有同名脚本!"));
                }
                //生成脚本
                else
                {
                    string content = File.ReadAllText(TEMPLATE_PATH);//从模板文件中读取内容
                    content = content.Replace("MyScript", _scriptName); //替换脚本名
                    content = content.Replace("time", DateTime.Now.ToString());//替换创建时间
                    content = content.Replace("ReplaceDescription", _description);//填入脚本功能描述
                    File.WriteAllText(path, content, Encoding.UTF8);//将修改后的内容写入新的脚本
                    AssetDatabase.Refresh();//马上刷新,方便在Project中直接看到新生成的脚本
                    ShowNotification(new GUIContent("Success!"));
                }
            }
        }
        else
        {
            EditorGUILayout.LabelField("请在Project面板中选择将要放置脚本的文件夹.");
        }
    }

    //校验脚本名(只能包含数字,字母,下划线且必须以字母或下划线开头)
    bool CheckScriptName(string scriptName)
    {
        Regex regex = new Regex("^[a-zA-Z_][a-zA-Z0-9_]*$");
        return regex.IsMatch(scriptName);
    }

    //脚本重复校验
    bool CheckRepeat(string selectDirPath)
    {
        DirectoryInfo dir = new DirectoryInfo(selectDirPath);
        FileInfo[] files = dir.GetFiles();
        string scriptName = _scriptName + ".cs";
        for (int i = 0; i < files.Length; i++)
        {
            if(files[i].Name == scriptName)
            {
                return true;
            }
        }

        return false;
    }

    //鼠标选中发生变化时调用
    private void OnSelectionChange()
    {
        //重绘窗口,刷新显示
        Repaint();
    }
}

猜你喜欢

转载自blog.csdn.net/Vitens/article/details/107587108