个人学习笔记,如有错误、疑问、建议,欢迎留言。
本文有关代码转载自:Unity3D 扩展编辑器实现创建Lua脚本 - 知乎 (zhihu.com)
声明:本文转载已取得原文章作者同意,有兴趣的可以关注原作者的知乎账号。
Charlotte - 知乎 (zhihu.com)


 上一篇文章介绍了第一种方式:Unity3D编辑器拓展——通过模板创建Lua脚本的两种方式(一)_Supernova Kai的博客-CSDN博客
 今天来介绍第二种方式,直接附上代码(代码后面部分为我个人的一些理解,如有错误,欢迎指出):

using UnityEngine;
using System.Collections;
using UnityEditor.ProjectWindowCallback;
using System.IO;
using UnityEditor;
public class CreateLua
{[MenuItem("Assets/Create/Lua Script", false, 80)]public static void CreateNewLua(){ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0,ScriptableObject.CreateInstance<CreateScriptAssetAction>(),GetSelectedPathOrFallback() + "/New Lua.lua",null,"Assets/Editor/Template/LuaComponent.lua"); //模板文件的路径}//获取Project界面选择的文件路径public static string GetSelectedPathOrFallback(){string path = "Assets";foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)){path = AssetDatabase.GetAssetPath(obj);if (!string.IsNullOrEmpty(path) && File.Exists(path)){path = Path.GetDirectoryName(path);break;}}return path;}
}
class CreateScriptAssetAction : EndNameEditAction
{public override void Action(int instanceId, string pathName, string resourceFile){//创建资源UnityEngine.Object obj = CreateAssetFromTemplate(pathName, resourceFile);//高亮显示该资源ProjectWindowUtil.ShowCreatedAsset(obj);}/// <summary>/// 通过模板创建新文件/// </summary>/// <param name="pathName">新文件路径</param>/// <param name="resourceFile">模板的路径</param>internal static UnityEngine.Object CreateAssetFromTemplate(string pathName, string resourceFile){string fullName = Path.GetFullPath(pathName); //获取要创建的资源的绝对路径//读取本地模板文件StreamReader reader = new StreamReader(resourceFile);string content = reader.ReadToEnd(); //读取到末尾reader.Close(); //关闭readerstring fileName = Path.GetFileNameWithoutExtension(pathName); //获取新文件的文件名//替换模板中的#SCRIPTNAME#为脚本名content = content.Replace("#SCRIPTNAME#", fileName);//写入新文件StreamWriter writer = new StreamWriter(fullName, false, new System.Text.UTF8Encoding(false));writer.Write(content); //写入新的内容writer.Close(); //关闭writer//刷新本地资源AssetDatabase.ImportAsset(pathName);AssetDatabase.Refresh();return AssetDatabase.LoadAssetAtPath(pathName, typeof(UnityEngine.Object));}
}

对上面代码的解释:
1、ProjectWindowUtil.StartNameEditingIfProjectWindowExists()方法:
StartNameEditingIfProjectWindowExists是一个在ProjectWindowUtil中的公有方法,其作用是将焦点设置到某文件并进入重命名,因为我们知道当我们右键创建代码的时候除了会选中该代码文件,同时还是处于重命名代码的状态的,此时代码尚未编译,当我们结束重命名后才真正进入到上面代码中CreateScriptAssetActionAction方法。
  其定义如下:

public static void StartNameEditingIfProjectWindowExists(int instanceID, EndNameEditAction endAction, string pathName, Texture2D icon, string resourceFile)

参数:
instaceID:

endAction:

pathName:新建文件的路径

icon:新文件的图标

resourceFile:模板的路径

 这个方法的流程如下:通过ScriptableObject.CreateInstance<>()方法创建一个实例,并进入重命名 --> 重命名结束时,会调用CreateScriptAssetActionAction方法,并将pathNameresourceFile作为参数传给Action方法。(也就是说这个方法的第二个参数endAction可以理解为就是结束重命名时需要执行的一个回调,就像参数名endAciton一样,一个重命名结束时执行的行为)

2、GetSelectedPathOrFallback()方法:

//获取Project界面选择的文件路径
public static string GetSelectedPathOrFallback()
{string path = "Assets";foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)){path = AssetDatabase.GetAssetPath(obj);if (!string.IsNullOrEmpty(path) && File.Exists(path)){path = Path.GetDirectoryName(path);break;}}return path;
}

GetSelectedPathOrFallback()方法用于获取当前选择的文件路径
Selection.GetFiltered()方法用于获取当前选择的对象;type参数为选择的对象类型,我们这里是Object,即所有的选择对象都会返回;mode参数用于进一步限制,我们这里mode是Selection.Assets,意思是仅返回Assets目录中的资源对象。

 上面第五行代码通过GetFiltered()方法获取所有选择的对象后,对返回的Object[]进行遍历,获取每一个对象,然后在用过第七行代码的AssetDatabase.GetAssetPath()方法获取该对象的路径。

AssetDatabase.GetAssetPath()方法通过传入资源对象本身,即可找到资源对象的路径。

 第八行代码,string.IsNullOrEmpty(path)判断路径是否为空,但是前面有一个取反!
!string.IsNullOrEmpty(path) && File.Exists(path)这段条件的含义是,当路径不为空,并且这个路径已经有文件时,执行if语句中的内容:Path.GetDirectoryName(path)方法,返回指定目录的根目录,并且break。(当路径不为空并且路径已经存在文件的情况时,给path重新赋值给根目录,并且break出去;因为路径已有文件的话在这个路径创建文件会把原来的文件给覆盖了)
 当不满足这个条件,也就是这个路径下没有文件的时候,返回这个路径。

3、CreateScriptAssetAction中的Action方法
 逻辑很简单,就是简单的文件读写,写读取模板的内容,把内容存到一个string;然后创建一个新文件,把这个string写入,正则替换一下,保存文件,刷新资源就行了。

Unity编辑器开发——通过模板创建Lua脚本的两种方式(二)相关推荐

  1. Unity编辑器开发——通过模板创建Lua脚本的两种方式(一)

    个人学习笔记,如有错误.疑问.建议,欢迎留言. 声明:本文不得以任何形式进行转载.  前言:在Unity编辑器的Project界面,可以直接右键创建C#脚本,而目前许多游戏公司使用的是tolua.xl ...

  2. 有效创建Oracle dblink的两种方式

    有效创建Oracle dblink的两种方式 两台不同的数据库服务器,从一台数据库服务器的一个用户读取另一台数据库服务器下的某个用户的数据,这个时候可以使用dblink. 其实dblink和数据库中的 ...

  3. Oracle创建Database Link的两种方式

    Oracle数据库如何创建Database Link呢?本文我们主要就介绍一下这部分内容,Oracle数据库创建Database Link有两种方式,一种是通过菜单,一种是通过SQL. 创建一个dbl ...

  4. python创建多线程_Python 多线程,threading模块,创建子线程的两种方式示例

    本文实例讲述了Python 多线程,threading模块,创建子线程的两种方式.分享给大家供大家参考,具体如下: GIL(全局解释器锁)是C语言版本的Python解释器中专有的,GIL的存在让多线程 ...

  5. 创建安卓模拟器的两种方式及常用Android命令介绍

    创建安卓模拟器有以下两种方式: 1>通过图形界面创建,在Eclipse中单击Windows->Android Virtual Device Manager启动图形界面窗口 2>如果用 ...

  6. 利用反射机制创建新类的两种方式及比较

    [0]README 0.1) 本文描述+源代码均 转自 http://blog.csdn.net/fenglibing/article/details/4531033 , 旨在深入理解 如何利用反射机 ...

  7. Linux 开机自动执行脚本的两种方式

    前言 很多情况下,我们都希望服务重启之后,很多应用都能自动启动,那么除了linux 提供的自启动配置之外,我们也可以在开机之后,通过指定 一些脚本的具体路径,或者是某个服务的启动命令具体路径,来进行服 ...

  8. 保姆级swap分区详解!手把手带你创建swap分区(两种方式,建议收藏)涉及fdisk、gdisk、df、parted、partprobe、mkswap、swapon、free、dd、od等命令

    Swap分区的详解 && 创建 什么是swap分区? 方法一:使用物理分区创建Swap分区 1. 利用fdisk / gdisk在磁盘上划出一个分区 1.1 lsblk -- 查看本机 ...

  9. spring boot controller 初始化_使用 Spring 快速创建 web 应用的两种方式

    介绍 本篇文章主要介绍,如何使用 Spring 开发一个 Web 应用. 我们将研究用 Spring Boot 开发一个 web 应用,并研究用非 Spring Boot 的方法. 我们将主要使用 J ...

最新文章

  1. MySQL导入导出数据和结构
  2. Google的Java开发规范
  3. Andriod --- JetPack (一):初识 JetPack
  4. hbase-site.xml 和 hbase-default.xml
  5. 想学会财务分析:先看懂三大表
  6. 未能正确加载包“Microsoft.Data.Entity.Design.Package.MicrosoftDataEntityDesignPackage
  7. J2SE下的路径问题
  8. laravel composer报错You can run './vendor/bin/upgrade-carbon' to get help in updating carbon and other
  9. linux下 Wowza安装与ffmpeg测试
  10. 用selenium实现百度贴吧自动发帖
  11. [玩法/技巧] Transmission 3.0 降级到 2.94 恢复数据的方法
  12. 操作系统引导详细过程
  13. 字节跳动工程师收入世界第五,2021年全球程序员收入报告出炉
  14. NASA准备在2021年推出最大望远镜!哈佛用棉花糖机造“肉”?
  15. Window API ShowWindow
  16. 论文投稿必看,审稿人意见互相矛盾,作者该怎么办?
  17. 微信公众 mysql回复图片_微信公众号开发之微信公共平台消息回复类实例
  18. B站的“擦边球”生意
  19. 仙之侠道2玖章各个任务详情_仙之侠道2玖章给Z武器的任务 | 手游网游页游攻略大全...
  20. css div自适应宽度

热门文章

  1. 利用接口:设计动物声音“模拟器”,希望模拟器可以模拟许多动物的叫声。
  2. VRTK案例011~020
  3. 基于Python的外卖用户评价情感倾向性分析
  4. virbr0怎么关闭_kvm下关闭virbr0与打开virbr0
  5. java sleep函数让出cpu_线程主动让出CPU
  6. 美国妈妈圣诞节送儿子iPhone:约法18章在先
  7. openfire error code=406 type=MODIFY 发文件
  8. 电源适配器 全球定义
  9. 二叉树结点深度(C语言)
  10. Python时间戳运用