Unity 自定义创建脚本模板
原理:以模板代码为底板,通过关键字替换来实现代码创建
两种实现方案
方案1
1.先准备好对应的代码模板,放到Assets\ScriptTemplates目录下
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.ProjectWindowCallback;
using UnityEngine;
public class CodeGenerator
{
private static string systemTemplatePath = "Assets/ScriptTemplates/SystemClass.cs";
[MenuItem("Assets/Create/C# System Script", false, 70)]
public static void CreateSystemCS()
{
//参数为传递给CreateEventCSScriptAsset类action方法的参数
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,
ScriptableObject.CreateInstance<CreateSystemCSScriptAsset>(),
GetSelectPathOrFallback() + "/New Script.cs", null,
systemTemplatePath);
}
public static string GetSelectPathOrFallback()
{
string path = "Assets";
//遍历选中的资源以获得路径
//Selection.GetFiltered是过滤选择文件或文件夹下的物体,assets表示只返回选择对象本身
foreach (Object obj in Selection.GetFiltered(typeof(Object), SelectionMode.Assets))
{
path = AssetDatabase.GetAssetPath(obj);
if (!string.IsNullOrEmpty(path) && File.Exists(path))
{
path = Path.GetDirectoryName(path);
break;
}
}
return path;
}
}
//要创建模板文件必须继承EndNameEditAction,重写action方法
class CreateSystemCSScriptAsset : EndNameEditAction
{
static string pattern = "SystemClass";
public override void Action(int instanceId, string pathName, string resourceFile)
{
//创建资源
Object obj = CreateScriptAssetFromTemplate(pathName, resourceFile);
ProjectWindowUtil.ShowCreatedAsset(obj); //高亮显示资源
}
private static Object CreateScriptAssetFromTemplate(string pathName, string resourceFile)
{
//获取要创建资源的绝对路径
string fullPath = Path.GetFullPath(pathName);
//读取本地的模板文件
StreamReader streamReader = new StreamReader(resourceFile);
string text = streamReader.ReadToEnd();
streamReader.Close();
//获取文件名,不含扩展名
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(pathName);
Debug.Log("text===" + text);
//将模板类中的类名替换成你创建的文件名
text = Regex.Replace(text, pattern, fileNameWithoutExtension);
//参数指定是否提供 Unicode 字节顺序标记
bool encoderShouldEmitUTF8Identifier = true;
//是否在检测到无效的编码时引发异常
bool throwOnInvalidBytes = false;
UTF8Encoding encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier, throwOnInvalidBytes);
bool append = false;
//写入文件
StreamWriter streamWriter = new StreamWriter(fullPath, append, encoding);
streamWriter.Write(text);
streamWriter.Close();
//刷新资源管理器
AssetDatabase.ImportAsset(pathName);
AssetDatabase.Refresh();
return AssetDatabase.LoadAssetAtPath(pathName, typeof(Object));
}
}
方案2
使用Unity 自带的模板功能进行配置模板代码
文件名
85-Other Scripts__Scriptable Object-MyClass.cs.txt
对应解释如下:
85 | Other Scripts | Scriptable Object | MyClass | .cs |
---|---|---|---|---|
Menu position | Menu name | Submenu name | Default name of the new created file | Created file extension |
注:子菜单名称可以设置多个,需要用"__"进行分割
文件内容
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#
}
}
Unity keys:
■ #NAME#
■ #SCRIPTNAME#
■ #SCRIPTNAME_LOWER#
■ #NOTRIM#
配置步骤
1.找到项目中的ScriptTemplates文件夹 新建脚本文件
2.补充代码模板,并按规则进行命名
3.如果想添加自定义的关键字,需要添加脚本进行对应关键字的替换
在自己的Unity工程中,创建Editor文件夹,在文件夹内创建脚本CustomScriptTemplate.cs
using UnityEngine;
using System.IO;
public class CustomScriptTemplate : UnityEditor.AssetModificationProcessor
{
/// <summary>
/// 此函数在asset被创建完,文件已经生成到磁盘上,但是没有生成.meta文件和import之前被调用
/// </summary>
/// <param name="newFileMeta">newfilemeta 是由创建文件的path加上.meta组成的</param>
public static void OnWillCreateAsset(string newFileMeta)
{
string newFilePath = newFileMeta.Replace(".meta", "");
string fileExt = Path.GetExtension(newFilePath);
if (fileExt != ".cs")
{
return;
}
//注意,Application.datapath会根据使用平台不同而不同
string realPath = Application.dataPath.Replace("Assets", "") + newFilePath;
string scriptContent = File.ReadAllText(realPath);
//这里实现自定义的一些规则
scriptContent = scriptContent.Replace("#SCRIPTNAME#", Path.GetFileName(newFilePath));
scriptContent = scriptContent.Replace("#CompanyName#", "CompanyName");
scriptContent = scriptContent.Replace("#Author#", "WangDouDou");
scriptContent = scriptContent.Replace("#Version#", "1.0");
scriptContent = scriptContent.Replace("#UnityVersion#", Application.unityVersion);
scriptContent = scriptContent.Replace("#CreateTime#", System.DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss"));
File.WriteAllText(realPath, scriptContent);
}
}
参考资料
https://www.twblogs.net/a/5b8c62db2b71771883327863/?lang=zh-cn
https://codeantenna.com/a/f7aoLrjFNm