Unity资源机制
1、概述
本文意在阐述Unity资源机制相关的信息,以及一些关于个人的理解与试验结果。另外还会提及一些因机制问题可能会出现的异常以及处理建议。大部分机制信息来源于官方文档,另外为自我验证后的结果。
2、资源
概述
Unity必须通过导入将所支持的资源序列化,生成AssetComponents后,才能被Unity使用。以下是Unity对Assets的描述:
Assets are the models,textures,sounds and all other “content”files from which you make your game。
资源(Asset)是硬盘中的文件,存储在Unity工程的Assets文件夹内。有些资源的数据格式是Unity原声支持的,有些资源则需要转换为源生的数据格式后才能被使用。
对象(UnityEngine.Object),代表序列化数据的集合,表示某个资源的具体实例。它可以是Unity使用的任何类型的资源,所有对象都是UnityEngine.Object基类的子类
资源与对象时一对多的关系。
|
|
|
|||
Audio Clip |
|
|
|||
Cubemap Texture |
|
|
|||
Flare |
|
|
|||
Font |
|
|
|||
Material |
|
|
|||
Meshes |
网格 |
.FBX .dae .3DS .dxf .obj |
|||
Movie Texture |
|
|
|||
Procedural Material Assets |
程序材质资源 |
|
|||
Render Texture |
|
|
|||
Text Asset |
|
.txt .html .htm .xml .bytes |
|||
Texture 2D |
|
|
除此之外,想使用Unity不支持导入,或者未经导入的资源,只能使用IO Stream或者WWW 方法,这些将在下文对应栏目中说明。
注意:AssetBundle不是资源组件,故无法用资源组件的方式载入,只能使用WWW或者AssetBundle相关接口载入与读取
GUID与fileID(本地ID)
Unity会为每个导入到Assets目录中的资源创建一个meta文件,文件中记录了GUID,GUID用来记录资源之间的引用关系。还有fileID(本地ID),用于标识资源内部的资源。资源间的依赖关系通过GUID来确定;资源内部的依赖关系使用fileID来确定。
InstanceID(实例ID)
Unity为了在运行时,提升资源管理的效率,会在内部维护一个缓存表,负责将文件的GUID与fileID转换成为整数数值,这个数值在本次会话中是唯一的,称作实例ID(InstanceID)。
程序启动时,实例ID缓存与所有工程内建的对象(例如在场景中被引用),以及Resource文件夹下的所有对象,都会被一起初始化。如果在运行时导入了新的资源,或从AssetBundle中载入了新的对象,缓存会被更新,并为这些对象添加相应条目。实例ID仅在失效时才会被从缓存中移除,当提供了指定文件GUID和fileID的AssetBundle被卸载时会产生移除操作。
卸载AssetBundle会使实例ID失效,实例ID与其文件GUID和fileID之间的映射会被删除以便节省内存。重新载入AssetBundle后,载入的每个对象都会获得新的实例ID。
资源的生命周期
Object从内存中加载或卸载的时间点是定义好的。Object有两种加载方式:自动加载与外部加载。当对象的实例ID与对象本身解引用,对象当前未被加载到内存中,而且可以定位到对象的源数据,此时对象会被自动加载。对象也可以外部加载,通过在脚本中创建对象或者调用资源加载API来载入对象(例如:AssetBundle.LoadAsset)
对象加载后,Unity会尝试修复任何可能存在的引用关系,通过将每个引用文件的GUID与FileID转化成实例ID的方式。一旦对象的实例ID被解引用且满足以下两个标准时,对象会被强制加载:
实例ID引用了一个没有被加载的对象。
实例ID在缓存中存在对应的有效GUID和本地ID。
如果文件GUID和本地ID没有实例ID,或一个已卸载对象的实例ID引用了非法的文件GUID和本地ID,则引用本身会被保留,但实例对象不会被加载。在Unity编辑器中表现为空引用,在运行的应用中,或场景视图里,空对象会以多种方式表示,取决于丢失对象的类型:网格会变得不可见,纹理呈现为紫红色等等。
MonoScripts
一个MonoScripts含有三个字符串:程序库名称,类名称,命名空间。