江枫

当个编辑器仔好难

   最近发现当工具仔的频率有点高,但是常用的接口总是记不住,决定还是整个笔记纪录一下都有哪些接口,以后回来查的时候也方便一些。

0.做个工具入口

1.用路径加载对象

2.搜索指定路径下的所有文件

3.修改完了如何保存资源

   

4.编辑器下到底应该如何卸载资源?

   使用第一种方式加载了对应的预制体后,发现这个东西居然不能用正常的方式卸载?!而且因为工具需要遍历的资源太多太大,这些资源无法及时卸载导致内存爆炸最后crash。接下来纪录一下为了卸载这个玩意儿我都试了哪些办法:

  • Resources.UnloadAsset

       很明显这个接口不行,因为这个接口只能释放资源,无法释放GameObject。调用卸载GameObject会报错:
       UnloadAsset may only be used on individual assets and can not be used on GameObject's / Components / AssetBundles or GameManagers

  • Object.DestroyImmediate

       这个接口也以失败告终,因为Unity会认为你在直接修改资源,如果直接删除对象会导致资源丢失,报错:
       Destroying assets is not permitted to avoid data loss.

  • Resources.UnloadUnusedAssets

       我尝试着先将资源的引用置为null,然后调用这个接口进行释放资源,虽然执行起来没有报错,但是我的内存仍然还是在上涨,并无法回到代码执行前的内存水平。
       我又试了一下多次运行这段代码,会出现内存仍然升高的现象,但是最终的值会稳定回到我第一次运行结束时的内存占用水平。

  • AssetDatabase.DeleteAsset

       看名字感觉像是跟LoadAssetAtPath接口像是配套的接口,但是 完 全 不 是 !他喵的这个接口是用来删除资源的,调一调资源全删掉!还好我有版本控制工具MMP。

   踩了四个坑,终于找到最终的接口了:
EditorUtility.UnloadUnusedAssetsImmediate();
   用了这个接口之后,内存稳如老狗,随便加载随便卸载,实在是太爽了!!!(编辑器下才有用哦)
   运行时应该还是要用Resources.UnloadUnusedAssets()进行卸载,不过现在暂时没用到,用到在研究吧~ 

5.加速importing

   Assetdatabase.StartAssetEditing/StopAssetEditing
   Unity官方的解释:Starts importing Assets into the Asset Database. This lets you group several Asset imports together into one larger import.通俗点讲就是对大量的import操作进行合批,进而加快import效率。StartAssetEditing/StopAssetEditing是成对出现的,Unity引擎内部有一个gLock字段用于记录StartAssetEditing/StopAssetEditing操作,每执行一次StartAssetEditing,gLock++,同样每执行一次StopAssetEditing,gLock--,当gLock=0时标志着一次import合批完成。为了实现import合批,unity会挂起StartAssetEditing/StopAssetEditing之间的所有Import和Refresh操作,等到StopAssetEditing后,一次性Import和Refresh。
StartAssetEditing/StopAssetEditing

6.给进程做个进度条吧~

   代码虽然很简单,但是每次都忘了接口叫啥,每次都要去之前的代码里复制,这里也稍微提一下吧:

7.readonly和const的区别

   readonly修饰的字段:其初始化仅是固定了其引用(地址不能修改),但它引用的对象的属性是可以更改的。
   const:定义的是静态常量,在对象初始化的时候赋值。以后不能改变它的值,属于编译时常量(编译时就已经确定的值)。不能用new初始化。不能与static一起使用,因为const已经是静态的了。

8.is/as与拆装箱

   is是一次类型检查,它只会检查对象是否与目标类型兼容,而不会进行类型转换。当然,is适用于所有类型,无论是值类型还是引用类型:

obj is Enum
obj is Vector2
obj is bool

   as是一次类型转换,首先它会检查对象是否与目标类型兼容,兼容则进行类型转换并拆箱成对应类型,如果不兼容则返回null。

as内部虽然做了一次类型检查,但是使用as的你并不知道检查结果,所以在使用as之后通常还是需要一次检查结果是否为null。
as无法用在可空类型上,即值类型无法使用as进行类型转换。

   那么我们在拆箱时具体要怎么办呢?

  • 对于引用类型,可以直接使用as进行拆箱,拆箱后记得判空
  • 对于值类型,只能先对类型使用is检查,然后进行强转。如

P.S.
   is和as都需要一个实例,也就是一个obj是否是另外一个类型,但是有的时候我们需要一些类型间的比较该怎么办呢?比如想判断一个类型是否为另外一个类型的子类,我们就可以使用下面的接口进行判断:

9.程序集与类型

   比如我们想获取某一个类型的所有子类,首先我们需要获取对应的程序集。
   通过类型可以直接获取类型所在的程序集,如

   其中如果我们想拿某个类型的父类,可以通过类型的.BaseType获取父类,但是如果你的类型继承自一个泛型父类,那么使用 targetType.BaseType == typeof(父类<>) 进行类型判断是不行的,因为在编译结束的时候,这个类的父类就已经是确定类型了,比如你的泛型传入的是int,那么类型的父类就是父类 而不是父类<> 了。

10.结果写入文件

   很简单,几行代码就解决了,但是代码是啥总忘,记一下。

11.如何计算函数耗时和内存?

文章大纲