C++玩转Unity资源,对象同序列化(上)

即时是一样多样文章中之次章节,覆盖了Unity5的Assets,Resources和资源管理

本文将于Unity编辑器和运行时有限只角度出发,主要探索以下简单地方内容:Unity序列化系统里细节以及Unity如何保护不同目标期间的高引用。另外还会见谈谈对象以及资源的技术实现差异。

译注:除非特别说明,下文中保有的“资源”均代表“Asset”。

正文内容是明亮在Unity中安快速加载与卸载资源的根底。正确的资源管理针对缩短加载时间并减少内存占用来说要。今天优先为大家享用上半局部内容。

1.1. 深刻理解资源及目标

在掌握Unity如何管万无一失地保管数据之前,首先要明白Unity是何许分辨并序列化数据的。首先第一接触,要正确区分资源(Asset)和对象(UnityEngine.Objects)。

Asset

资源(Asset)是硬盘中的公文,存储于Unity工程的Assets文件夹内。例如,纹理(Texture),材质(Material)和FBX文件等,它们还是资源。一些资源的数码格式是Unity原生支持之,例如材质。有些资源虽然需要换为原生的多少格式后才能够吃Unity使用,例如FBX文件。

UnityEngine.Object

UnityEngine.Object,或者说为充分写字母O开头的Object——对象,代表序列化数据的聚集,表示有资源的切切实实实例。它可是Unity引擎使用的任何项目的资源,例如网格,Sprite,音频剪辑还是动画剪辑。所有的靶子(Object)都是UnityEngine.Object基类的子类。

特殊的Object类型

几所有的靶子(Object)类型且是外盖之,其中起三三两两种比较新鲜的花色。

  1. ScriptableObject为开发者提供了同拟便捷的体系,供开发者自定义数据类型。这些类别可以吃Unity直接序列化或反序列化,并在Unity编辑器的检视器窗口被展开操作。
  2. MonoBehaviour供了链接MonoScript的容器。MonoScript是同样栽内部数据类型,Unity用她保存对某个特定程序集和命名空间被一定脚本类的援,MonoScript本身不分包其他实际的可实行代码。

同一对准多关系

资源(Asset)与目标(Object)是平种植同等针对多的干,即一个资源文件或者会见连多独Object。

1.2. 对象中的援

抱有UnityEngine.Objects都好引用其他的UnityEngine.Objects。这里“其他的Object”可能存在被同的资源文件中,或需由旁资源文件导入。例如,一个材质Object通常有一个或者多个纹理Object的援。这些纹理Object一般是自一个还是多只纹理资源文件被导入的(例如PNG或JPG文件)。

序列化后,这些引用由个别有的数据整合:文件GUID和地方ID。文件GUID用于识别资源(Asset)文件被目标资源(Resource)的仓储位置。而本土唯一(1)的ID负责鉴别单个资源文件中之Object,因为一个资源文件或者会见蕴藏多只Object。

文件GUID(.meta)

文件GUID存储于.meta文件中。Unity会在首蹩脚导入资源文件时生成.meta文件,并同资源文件共囤在平的目录中。

上述的辨识和援系统可以应用文本编辑器查看:

  1. 创建一个崭新的Unity工程,更改编辑器设置,将EditProject
    Settings
    Editor中的Version Control设为Visible Meta
    Files
    ,并将Asset Serialization倘若为文本。
  2. 新建材质并向工程被导入一个纹理。将材与给场景被的一个立方,保存状况。

使文本编辑器打开这材质对应之.meta文件。在文件上附近见面生出一行给标记也“guid”,该行定义了材料资源文件的公文GUID。

fileFormatVersion: 2
guid: 6839b719d14310c4f945de352bac3767
timeCreated: 1472566765
licenseType: Pro
NativeFormatImporter:
  userData: 
  assetBundleName: 
  assetBundleVariant: 

本土ID(具体文件)

设用查看本地ID,使用文本编辑器打开材质文件,材质Object的定义大致如下:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000

Material:

serializedVersion: 6

... more data ...

当面的例子中,前面来&符号的数字就是材料的本地ID。如果这个材料的Object位于一个文书GUID为“abcdefg”的资源文件被,则该材质Object的绝无仅有识别符就是文本GUID“abcdefg”和地面ID“2100000”的做。

1.3. 为何而为此文件GUID和本土ID?

做事流程

于Unity中,为什么而采取文件GUID和当地ID这套系统啊?答案是为稳定服务,也是为了提供相同法灵活的、无关具体平台的劳作流程。文件GUID提供了文本存储位置的悬空,这样一个文件GUID就相应一个现实的公文,这个现实的文件存储在什么岗位吗不怕无关紧要了。因此我们才能够随便活动是文件要未坏所有有关Object对之文件的援。

任何资源(Asset)文件中都可能含有(或经导入产生)多单UnityEngine.Object资源(Resource),因此要一个地面ID来针对其中的Object做肯定区分。

假如与资源文件相关联的公文GUID丢失,则怀有对该资源文件被的Object的援都见面于弄坏。这即是得保证.meta文件具有跟资源文件一律之公文名并存储在相同目录下的因由。注意Unity会重新转丢失或叫剔除的.meta文件。

Unity编辑器维护映射表

Unity编辑器负责掩护一摆文件路径和公事GUID之间涉及的映射表。只要资源文件被读取或导入,这个映射关系虽会让起,映射会将资源的具体位置和资源的公文GUID进行关联。Unity编辑器处于打开状态时,假而一个文本之.meta意外遗失,并且该资源文件之路径没有改动,编辑器可以确保是资源会被分配至平等之文书GUID。

假如以Unity编辑器处于关闭状态时丢失.meta文件,或资源文件为活动但尚未运动对应的.meta文件时,所有对资源文件中之Object的援都见面丢掉。

1.4. 复合资源和导入器

资源导入器

刚而前方深入理解资源与目标中所说的同等,不能够让Unity直接支持之资源类型不能不透过导入才方可采取——使用资源导入器来就。这些导入器是机动调用的,您为足以利用AssetImporter在本子中调用API及其子类。例如,在导入单独的纹路资源例如PNG和JPG时,TextureImporter
API提供了导入时一旦以的相干设置的访问。

导入过程最终的结果是千篇一律多重UnityEngine.Object。在Unity编辑器中,这些目标见面具体表现为父亲资源下之多个子资源,例如当Sprite
Atlas导入的纹路材质,其属下会起差不多只嵌套的Sprite。每一个对象还见面使用相同之公文GUID,因为它们的发源数据还存储在和一个资源文件中。它们于纹理资源遭到的具体分工作则动用当地ID来完成。

Library文件夹

导入过程遭到见面拿来自资源转换为配合配Unity编辑器中选定的目标平台的格式。导入过程可能会见拉一些重量级操作,例如纹理压缩。如果老是打开Unity编辑器时都使实行这些操作,那效率就是不过没有了。

为了解决当下同题材,我们用资源导入的结果缓存在Library文件夹着。具体就是,导入进程的结果以会晤储存在坐资源文件GUID头两号作为名称的文书夹着。这些文件夹位于
Library/metadata/
目录下。各个不同的靶子会于序列化后存储于一个二进制文件被,文件使用资源文件之GUID来定名。

立马对拥有资源都是一致的,不仅仅是非原生资源。只不过Unity原生支持之资源不待针对那个进行更换或序列化处理。

达成半部分的内容要介绍了资源(Asset)和目标(UnityEngine.Objects)的别,以及文件GUID和本土ID二者的涉嫌和差异。下半部分以为大家介绍第三种ID:对象的实例ID,并探这些ID对资源在内存和显存中之加载与卸载分别拥有怎样的图。

Footnotes(脚注)

  1. 以文件被,本地ID是绝无仅有的。即以一个资源文件被,里面包含的当地ID都是勿还的。
  2. 以中,这种缓存被称作PersistentManager。实际的更换工作于当Unity的C++
    Remapper类中开展,Remapper类没有提供其他C# API调用接口。
  3. 运行时创造资源的示范是于本子中创造Texture2D对象:var myTexture = new Texture2D(1027, 768);
  4. 程序运行时对象并从未让卸载却让从内存中移除的图景一般会有在Unity失去了对图纸内容之主宰的下。例如,当手机用被吊起于并受劫持在后台运行。这种情况下,手机操作系统通常会用富有的图形资源从GPU显存中野卸载。之后APP再回来前台运行时,Unity不得不重新于GPU上传要的料、着色器和网格数据,以便恢复状况的正常化渲染。

至这整个Unity内部资源管理与目标引用和序列化的始末即收了,希望看了本文的而对什么合理分配Unity项目结构都起矣于明晰的定义。

原文链接:http://unity3d.com/cn/learn/tuto …
tion?playlist=30089
感谢Unity官方翻译组成员“E.A.S”对本文翻译所做的孝敬。
转载请注明来源:Unity官方中文社区
(forum.china.unity3d.com)。请不私自更改任何版权说明信息。