Unity资源
Asset 和 UnityEngine.Objects
- 资源(Asset)是硬盘文件
在unity工程Assets文件夹内,如纹理,FBX,材质等属于资源,其中有些是unity原生支持的,例如,材质。有些资源则需要转换为原生的数据才能被unity所支持,例如,FBX。
- UnityEngine.Object
代表序列化数据的集合,表示具体的某个资源的实例。
- 特殊的Object类型
有两种比较特殊的对象
- ScriptableObject 为开发者提供的便捷操作,供开发者进行自定义数据类型,并且可以在检视面板进行操作。
- MonoBehaviour 提供了链接容器MonoScritp是一种内部数据类型,Unity用它保存对某个特定程序集和命名空间中特定脚本类的引用,MonoScript本身不包含任何实际的可执行代码
- 资源(Asset)与对象(Object)是一种一对多的关系,即一个资源文件可能会包括多个Object
对象之间的引用
所有UnityEngine.Objects都可以引用其他的UnityEngine.Objects,可存在相同的资源文件中,或者从其他文件导入,例如,一个材质Object通常有一个或多个纹理Object的引用
经过序列化后,这些引用由两部分数据组成:文件GUID和本地ID
- 文件GUID用于识别资源(Asset)文件中目标资源(Resource)的存储位置。
- 本地ID负责识别单个资源文件中的Object
文件GUID(.meta)
使用过Unity的都会发现,每一个导入Unity里面的都会为其生成一个.meta文件。
我们使用文本编辑器进行查看:
将Edit - Project Settings - Editor中的Version Control设为Visible Meta Files,并将Asset Serialization设为文本,导入一个材质,生成一个prefab放入场景,我们编辑这个材质对应的.meta文件,如下图有个GUID即,目标资源的ID
我们查看本地文件打开prefab文件
我们来看看一个prefab引用一个材质,他们的meta是怎么记录引用的
打开cube.prefab &符号的是本地ID,下面就是引用的一些组件,查看MeshRenderer里面的材质guid
打开材质的meta
这样就知道prefab是引用的资源sd.mat了
为什么要用GUID和ID呢?
unity为了稳定服务,提供一套灵活的,无关平台的工作流程。GUID提供了一个具体的文件,这个具体的文件存储在什么位置无关紧要,因此随意移动而不会破坏相关Object对这个文件的引用。
任何资源(Asset)文件中都可能含有(或通过导入产生)多个UnityEngine.Object资源(Resource),因此需要一个本地ID来对其中的Object做明确区分
必须保证.meta文件具有和资源文件相同的文件名并存储在同一目录下。注意Unity会重新生成丢失或被删除的.meta文件
- 怎么根据GUID查找路径呢?
Unity编辑器负责维护一张文件路径与文件GUID之间关系的映射表。只要资源文件被读取或导入,这个映射关系就会被建立,映射会将资源的具体位置和资源的文件GUID进行关联。Unity编辑器处于打开状态时,假设一个文件的.meta意外丢失,并且该资源文件的路径没有改变,编辑器可以保证这个资源会被分配到相同的文件GUID。
如果在Unity编辑器处于关闭状态时丢失.meta文件,或资源文件被移动但没有移动对应的.meta文件时,所有对资源文件中的Object的引用都会丢失。
Library文件夹
- 资源导入
不能被Unity支持的资源类型必须进过资源导入器来完成,这些是自动调用的 - Library/metadata/目录
导入过程中会将源资源转换为匹配Unity编辑器中选定的目标平台的格式。导入过程可能会牵涉一些重量级操作,例如纹理压缩。如果每次打开Unity编辑器时都要执行这些操作,那效率就太低了。为了解决这一问题,我们将资源导入的结果缓存在Library文件夹中。具体就是,导入进程的结果将会存储在以资源文件GUID头两位作为名称的文件夹中。这些文件夹位于 Library/metadata/ 目录下。各个不同的对象会被序列化后存储在一个二进制文件中,文件使用资源文件的GUID来命名。
这对所有资源都是一样的,不仅仅是非原生资源。只不过Unity原生支持的资源不需要对其进行转换或序列化处理