在用Unity开发游戏的时候,由于经常要用到不同的脚本模板,特别是在写Editor和AttributeDrawer这类脚本时很想能实现一定规则的字符串替换,所以就写了这么个脚本实现自定义模板+自定义字符串替换的功能。
脚本内容主要分为五部分:
Action:新建脚本时调用的内容
ReplaceKeyword:对新建脚本中的字符串进行替换
InvokeWhileCreateScript:新建脚本时调用的内容(主动调用)
CreateTemplateLoader:根据自定义模板创建菜单
FileIO:一些文件操作
一般这些内容是应该分开几个脚本写的,但为了“携带方便”,就把它们全都写在一起了
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Text.RegularExpressions;
namespace UnityEditor.ProjectWindowCallback{
public class UserDefinedScriptAction : UnityEditor.ProjectWindowCallback.EndNameEditAction
{
static readonly string TemplatesDir = EditorApplication.applicationContentsPath + "/Resources/ScriptTemplates/MyTemplates/";
#region Action
public override void Action(int instanceId, string pathName, string resourceFile)
{
//创建资源
Object obj = CreateAssetFormTemplate(pathName, resourceFile);
//高亮显示该资源
ProjectWindowUtil.ShowCreatedAsset(obj);
}
internal static Object CreateAssetFormTemplate(string pathName, string resourceFile)
{
//Debug.Log (pathName + "-" + resourceFile);
//获取要创建资源的绝对路径
string fullName = Path.GetFullPath(pathName);
//读取本地模版文件
StreamReader reader = new StreamReader(resourceFile);
string template = reader.ReadToEnd();
reader.Close();
//获取资源的文件名
string fileName = Path.GetFileNameWithoutExtension(pathName);
string content = RepalceKeyword (template, fileName);
//写入新文件
StreamWriter writer = new StreamWriter(fullName, false, System.Text.Encoding.UTF8);
writer.Write(content);
writer.Close();
//刷新本地资源
AssetDatabase.ImportAsset(pathName);
AssetDatabase.Refresh();
return AssetDatabase.LoadAssetAtPath<Object>(pathName);
}
#endregion
#region RepalceKeyword
const string startEndTag = "@@";
const char divChar = ':';
static string RepalceKeyword(string template, string fileName){
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder (template);
stringBuilder.Replace ("#ScriptName#", fileName);
stringBuilder.Replace ("#CompanyName#", PlayerSettings.companyName);
stringBuilder.Replace ("#ProductName#", PlayerSettings.productName);
stringBuilder.Replace ("#CreateTime#", System.DateTime.Now.ToString ("G"));
foreach (Match match in Regex.Matches (stringBuilder.ToString (), "#CreateTime@.*#")) {
if (match.Success) {
string