Unity中有两处用到了Asset的概念,一是Unity的工程目录Assets;二是打包系统AssetBundles。
首先,我们来看看unity创建工程的几个目录,包括:Assets,Library,Packages,ProjectSettings。
Assets 是Unity 的资源目录,只有被放在这里的资源才会被Unity 识别到。
Library 存放的是经过Unity 处理的Asset 里的资源文件。
Packages 用于存储Unity 分离的Packages 组件,是新的属性。
ProjectSettings 存放项目设定。
另有一个obj 目录用于存放编译的代码文件。
复制工程的时候只需要Assets,Packages,ProjectSettings,Library会在打开Unity的时候进行转化。
同理,切换平台往往需要重新处理资源文件,需要大量时间。
AssetBundle 是对Asset 的归档后的格式,类似于 zip文件,但是是针对 Asset 的,具有平台差异性。
在Unity中,通过后缀名判断文件类型。包括Unity原生支持的格式,以及需要 Importer 处理的格式。
除了Unity 内置支持的对象之外,还有 ScriptableObject 和 MonoBehaviour 的对象。举个例子,一个Prefab是一个Asset,这个Asset 里面包含有大量的对象。
对象在Unity中可以相互引用,引用的资源可能不在同一个Asset里,如UGUI中的Image需要引用一个Atlas图集的Sprite。Unity 将序列化分为第一步 File GUID 用来标识 Asset 的位置,由Unity自动生成,并且存储在同名的.meta文件中。
另外有一个Local ID作为对象在Asset中的唯一标志,Unity内部有一个GUID和路径的映射表,每次有变更都会自动修正!因此可能会生成不一样的GUID,丢失会有Missing标志。
Library中的文件存储
打开Library/metadata的目录,可以看到很多的特殊命名文件,这其实是用FileGUID的前两位命名的文件夹。
Instance ID
Unity中有PersistentManager用以将FileGUID和LocalGUID转化成一个递增的唯一整数,也就是InstanceId。有新对象的时候简单的递增。
PM维护上述三个数字的映射关系,加快查找和加载的速度。
资源生命周期
Unity启动时,PM对启动场景以及Resources目录下的对象进行初始化,在运行时导入Asset或者从远程下载来的AssetBundle加载的Object都会产生新的InstanceID。
Obeject会被自动加载。
当Asset不再使用时,会卸载对应的,没有任何引用的对象,使用Resources.UnloadUnusedAssets触发。从Resources目录加载的对象被卸载后仍能快速被加载使用。
从AB中得到的对象会被立刻卸载,true卸载会使得所有的ID都会失效,false卸载不会直接销毁对象,但是会将三个ID的联系删除,也就是再次引用Object无法自动重加载。
Object中断了与原来AssetBundle的联系后再加载,不会重用原来的Object,而是新建InstanceID,导致内存中有多份重复的资源。
拓展阅读:
《深度剖析PersistentManager.Remapper内存占用》
《Unity文件、文件引用、Meta详解》
《程序丨入门必看:Unity资源加载及管理》
网友评论