当然,我是用MAYA导入的,U3D引擎对于MAYA的支持还是不错的,但是也需要注意,不要用中文的目录结构,百度搜索编、程、回、忆、录之unity3d,最好直接从MAYA的工程文件夹中导入,最好在导入MESH前先吧贴图文件放到相应的文件夹,或者相关文件夹的子文件夹。
在我滑绝们导入场景文件的时候,需要在导入设置中勾选创建碰撞,这样导入的场景我们就可以踩在上面了。(这跟我们添加碰撞组件是有些不同)
这是涵盖Assets,Resources和资源管理的一列文章中的第二篇。
这篇文章涵盖了Unity序列化系统的内部原理和Unity是如何在不同的Objects间保持健壮的引用的,包括Unity编辑器与运行时。也讨论了Objects和Assets在技术上的区别。这里涉及的主题对理解如何高效地加载和卸载Unity资源起到很重要的作用。合适的资源管理的关键是hi保持短的加载时间和较低的内存使用。
为了明白Unity是如何合理地管理数据的,了解Unity是如何标识和序列化数据是很重要的。第一个关键点就是区分Assets和UnityEngine.Objects。
Asset就是硬盘的上的一个文件,存储在Unity工程的Assets文件夹。Textures,3d模型或音频都是常见的Assets类型。一些Assets包含了Unity的内部数据类型,如材质,而另一些Assets需要处理成Unity内部数据类型,如FBX文件。
UnityEngine.Object或具有大写'O'的对象,是描述特定资源实例的一组集合。可以是Unity使用的任何资源类型,比如mesh,sprite,AudioClip或AnimationClip。所有这些Objects都是继承咐罩自 UnityEngine.Object 。
虽然大多数类型都是内置的,但有两种特殊类型:
Assets和Objects是一对多的关系,也就是说任何给定的Asset文件包含一到多个的Objects。
所有的nityEngine.Objects可以引用其他UnityEngine.Objects。这些Objects可能是在同一个Asset文件,也可能从其他Asset文件引入。比如一个材质通常引用一个或多个Texture Objects。这些Texture Objects通常从一个或多个texture Asset文件引入(比如Pngs,Jpgs)。
当序列化的时候,这些引用由两个独立的数据组成:File GUID和Local ID。File GUID标识目标Asset文件保存在哪里。局部唯一的Local ID标识Asset文件内的每个Object,因为Asset可能包含多个Objects。
File GUID保存在.meta文件。这些.meta文件是在Unity引入Asset的时候生成的,并且存储在和Asset同一个目录下。
以上的标识码和引用关系可以通过文本编辑查看:创建一个新的UnityObject,修改Editor Setting暴露显示Mate文件,序列化Assets为text。创建一个material,然后导入texture到工程。把这个material指认给一个场景中的cube并保存。
使用文本编辑器打开跟上满material关联的.meta文件,靠近顶部会出现标记为"guid"的信息。这一行定义了material Asset's文件的GUID。而查找Local ID需要使用文本编辑器打开material文件。material Object's 的定义是这样的:
在上面的例子中,&之后的数据就是material的Local ID。如果这个material Object在Asset中GUID标搭举识为"abcdefg",可以将material 对象唯一地标识为文件GUID "abcdefg"的组合,Local ID为"2100000"。
为什么需要Unity的File GUID和Local ID? 回答的坚定的,因为它提供了一个灵活的、不依赖平台的工作流。
文件GUID为文件特定路径提供了抽象描述。只要一个特衡枝闹定的文件GUID与特定的文件关联起来,那么文件在磁盘的路径变得无关紧要了。文件可以自由移动,而不需要更新所有引用这个文件的Objects。
任何一个Asset可能包含(或通过import产生)多个UnityEngine.Object 资源,这个时候需要Local ID明确的区分不同的Object。
如果一个File GUID关联的Asset文件丢失了,对该Asset的所有对象的引用也会丢失。所以.meta文件必须要保存在跟它关联的同名文件目录下,这很重要。注:Unity会重新生成删除的或丢失的.meta文件。
Unity Editor有Paths到GUIDs的映射表。无论Asset加载还是引入,都会记录在映射表。映射表由Asset指定路径链接到Asset File GUID。如果Unity Editor打开的状态下,.meta文件丢失,并且Asset路径没有变化,Editor能够确保Asset保留相同的File GUID。
如果Unity Editor在关闭状态下丢失了.meta文件,或者Asset路径变化了但.meta没有跟着移动,那么所有引用该Asset的Objects都会被破坏。
在1.1内部Assets和Objects章节说过,非Unity原生Asset类型必须导入到Unity。这是通过asset导入器来完成的。虽然这些导入器通常自动调用,但它们也可以通过 AssetImport API暴露接口。比如, TextureImporter API在导入单个texture Assets(如PNG文件)提供了访问设置的接口。
导入的结果就是引入一个或多个UnityEngine.Objects。这些Objects在Unity Editor是可见的,以父Asset下有多个子Asset形式显示,比如多个sprites嵌套在一个texture Asset,会当成sprite图集导入。其中这些每个Object共享一个File GUID,因为他们的源数据保存在相同的Asset文件。它们将通过导入的texture Asset内部的Local ID进行区分。
导入进程会将源Asset转化为适合所选择目标平台的Asset。导入进程可能包含了一些重要的 *** 作,比如texture压缩。因为导入进程通常是一个耗时的进程,被导入的Asset缓存到Library文件夹,避免下次启动Editor又重新导入Assets。
切确的说,导入后的内容存储在以对应Asset的File GUID前两位数字命名的文件夹中。这个文件夹存储在Library/metadata/文件夹中。Asset中单个的Objects被序列化到一个名字与Asset的File GUID相同的二进制文件中。
导入进程对所有的Assets有效,不仅仅对非原生Assets。原生assets不需要漫长的转换过程或重新序列化。
File GUIDs和Local IDs都是健壮性比较好的,但GUID比较慢,运行时需要消耗更多性能。Unity内部维护一个缓存,它将File GUIDs和Local IDs转化成简单的,唯一的整数。当新的Objects在缓存注册的时候,会被分配一个简单的,单调递增的整数,这就叫Instance ID。
缓存维护了给定的Instance ID,File GUID和定义Object源数据位置的Local ID与 Object在内存中的instance(如果有的话)之间的映射。解析Instance ID可以快速返回Instance ID代表的加载Object。如果目标Object还没有加载,File GUID和Local ID可以解析到Object源数据,可以让Unity及时加载出Object。
项目启动的时候,Instance ID缓存初始化所有的Objects(如场景中的引用),只要这些Objects在Resources文件夹。另外,当新的assets在运行时导入进来或从AssetBundle加载Objects时,Instance ID会加进缓存中。当提供访问指定File GUID和Local ID的AssetBundle卸载(uploaded)时,Instance ID才会从缓存中移除。发生这种情况的时候,Instance ID,File GUID,Local ID之间的映射会被删除(节约内存)。如果这个AssetBundle重新加载了,会从这个重新加载的AssetBundle为加载出来的每个Object创建一个新的Instance ID。
深度讨论AssetBundles卸载的含义,这看 Managing Loaded Assets 章节和 AssetBundle Usage Patterns 文章。
在一些平台上,一些事件可以强制让Objects强制从内存中移除。比如,当IOS app暂停的时候,图形Assets会从图形内存中卸载。如果这些Objects是从AssetBundle加载出来的就会被卸载掉,并且Unity不能够重新加载这些源数据。任何现存的引用这些Objects的对象视为无效。前面的这种情况,场景中可能出现不可见的meshes或紫红色的图片。
实践Tips:运行时,上述控制流并非字面上那么精确。当运行时,有大量大量加载 *** 作的时候,File GUIDs和Local IDs表现没有那么好。当创建一个Unity项目的时候,File GUIDs和Local IDs切确地映射成了一种更简单的格式。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)