这是涵盖Assets,Resources和资源管理的一列文章中的第二篇。
这篇文章涵盖了Unity序列化系统的内部原理和Unity是如何在不同的Objects间保持健壮的引用的,包括Unity编辑器与运行时。也讨论了Objects和Assets在技术上的区别。这里涉及的主题对理解如何高效地加载和卸载Unity资源起到很重要的作用。合适的资源管理的关键是hi保持短的加载时间和较低的内存使用。
为了明白Unity是如何合理地管理数据的,了解Unity是如何标识和序列化数据是很重要的。第一个关键点就是区分Assets和UnityEngineObjects。
Asset就是硬盘的上的一个文件,存储在Unity工程的Assets文件夹。Textures,3d模型或音频都是常见的Assets类型。一些Assets包含了Unity的内部数据类型,如材质,而另一些Assets需要处理成Unity内部数据类型,如FBX文件。
UnityEngineObject或具有大写'O'的对象,是描述特定资源实例的一组集合。可以是Unity使用的任何资源类型,比如mesh,sprite,AudioClip或AnimationClip。所有这些Objects都是继承自 UnityEngineObject 。
虽然大多数类型都是内置的,但有两种特殊类型:
Assets和Objects是一对多的关系,也就是说任何给定的Asset文件包含一到多个的Objects。
所有的nityEngineObjects可以引用其他UnityEngineObjects。这些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产生)多个UnityEngineObject 资源,这个时候需要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都会被破坏。
在11内部Assets和Objects章节说过,非Unity原生Asset类型必须导入到Unity。这是通过asset导入器来完成的。虽然这些导入器通常自动调用,但它们也可以通过 AssetImport API暴露接口。比如, TextureImporter API在导入单个texture Assets(如PNG文件)提供了访问设置的接口。
导入的结果就是引入一个或多个UnityEngineObjects。这些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切确地映射成了一种更简单的格式。
Input。从今日头条得知unity脚本程序的输出和输入主要都在Input类中实现。Unity是微软开发的一款轻量级、可扩展的IoC框架,可通过代码或者XML配置文件的形式来配置对象和对象直接的关系。
你这样学不对。
我给你说说一般的路线,再给你说为啥以Python做Unity开发不好。
先学Unity的场景编辑器可视化的部分(比如地形和基本物理设置),这部分不涉及太多编程。在学动画调节部分。慢慢的引入编程控制。然后要使用联网游戏,学习网络功能。最后学习shader编程。第一趟学习过程的迭代(以上所有环节),以网上的系列教程或书籍教程为主。然后第二遍,在重新认识场景编辑器,以官方参考手册为主,选择几个常用的插件,这一次应该有实践项目。因为Unity本身也是巨大的体系,所谓Unity专家也只是对某一个方面特别在行,你要有着重点和切入点,这以你的游戏类型和风格为标准(你是做2D/3D,你是重视觉呈现还是玩法,有没有联网功能等)
Unity的脚本运行环境是Mono,是一个开源的NET框架,你知道NET的话就应该知道它是和编程语言无关的(都会编译成 CLI 汇编)。Mono绑定了多个语言,官方的是C#,一个第三方开发者绑定了Python也就是Boo,而Unity公司在这个Boo之上绑定了JavaScript也就是UnityScript,但是Boo(基于Mono CLR实现)并不是那个真正的Python(基于C语言实现),它们的运行时完全不同。而且Boo和UnityScript的编译后的 CLI 汇编效率要比 C# 的低。Unity 官方也在一步步的降低对Boo和UnityScript的支持。
但是学Python和做Unity游戏有关系吗?
有,但不是用在Unity本身的开发上,可以用Python-WSGI 编写游戏服务端,并搭建在云服务器上。当然替代的技术有 PHP、Java 等
Unity会下载Assetbundle本地中,它的工作原理是先通过(版本号和下载地址)先在本地去找看有没有这个Assetbundle,如果有直接返回对象,如果没有的话,在根据这个下载地址重新从服务器或者本地下载。这里版本号起到了很重要的作用,举个例子,同一下载地址版本号为1的时候已经下载到本地,此时将版本号的参数改成2 那么它又会重新下载,如果还保持版本号为1那么它会从本地读取,因为本地已经有版本号为1的这个Assetbundle了。你不用担心你的资源本地下载过多,也不用自己手动删除他们,这一切的一切Unity会帮我们自动完成,它会自动删除掉下载后最不常用的Assetbundle ,如果下次需要使用的话只要提供下载地址和版本后它会重新下载。
我们在聊聊Assetbundle 中的脚本,在移动平台下Assetbundle里面放的脚本是不会被执行的,还记得我们打包前给两个Prefab挂上了脚本吗?在手机上将Assetbundle下载到本地后,加载进游戏中Prefab会自动在本地找它身上挂着的脚本,他是根据脚本的名来寻找,如果本地有这条脚本的话,Prefab会把这个脚本重新绑定在自身,并且会把打包前的参数传递进来。如果本地没有,身上挂的条脚本永远都不会被执行。
在Prefab打包前,我在编辑器上给脚本中的变量 name 赋了不同值,当Prefab重新载入游戏的时候,它身上脚本的参数也会重新输出。
如果你的Assetbundle中的Prefab上引用的对象,那么这样做就会出错了,你需要设定他们的依赖关系。或者运行时通过脚本动态的载入对象。
大家在玩游戏的时候可能经常会遇到卡顿,延迟,死机,不流畅等等问题,那么这些问题是怎么引起的呢如何去尽量的减少这些情况的发生呢这些问题对于游戏开发者来说是必须要面对的问题, 也是必须要解决的问题。
上面我们例举在游戏运行的过程中可能会遇到的一些问题, 每种问题引起的原因有很多多,但是我们可以从大方向对整体游戏进行优化,使游戏整体性能更优,从而减少这些情况的发生。对于性能优化我们大体可以从四个大方向去优化,即:CPU,GPU, 内存以及网络和IO,下面给大家一一讲解:
CPU优化,在游戏中CPU主要分担着运算的责任,因此像短时间大量的计算从而导致画面不流畅,电量消耗大,发热严重等情况都可能是因为CPU导致的。针对这些情况我们就需要对CPU优化,那么CPU的优化说白了就是对运算的优化,大家应该尽量减少大量运算或者短时间的大量运算,对此大家可以从四方面着手。一是将计算分散到多个逻辑中,减少短时间的大量运算。二是将可以缓存的数据尽量缓存起来,从而避免那些重复的计算。三是减少CPU对资源的申请、销毁与调配。四是使用合理的算法和数据结构,这个也是CPU优化中最重要的。
GPU优化,GPU的职责就是负责游戏中所有的图像、特效的渲染。GPU的消耗过高会导致游戏画面卡顿、画质降低、手机发热等情况,严重影响游戏体验。对于游戏来讲这是致命的。关于CPU优化大家可以从以下几方面入手:
1、资源优化,比如合理规划图集,指定合理的粒子效果,约定模型的三角面数
2、简化着色器,使用多级纹理与材质贴图技术相结合
3、使用LOD技术、遮挡剔除等技术,减少GPU绘制的数量
4、针对不同的系统平台使用对应的压缩格式。
5、优化显存带宽
游戏渲染可以说是游戏的心脏,所以GPU的优化显得尤为重要,需要开发者格外的重视
内存优化,内存的功能我就不多介绍了, 相信大家都了解。由于内存不足所导致的问题有闪退,卡死等。对于内存的优化,一是降低资源的大小,比如剔除不需要的资源、对资源进行压缩等;二是及时动态的加载和卸载资源,这样可以大大的减少瞬时内存的压力,减少因内存浪费而给游戏带来不必要的消耗。三是降低资源的质量,这是一种有损的优化,不到最后一般不用,当然我们也可以根据不同的设备使用不同质量的资源,将损失降到最低。
网络和IO优化, 他们主要负责资源的加载, 可能是网络的或者本地的。网络不好,或者资源加载时间过长会让大大降低用户体验。因此在CPU、GPU、内存优化后我们同时也不能忽略网络与IO优化,对于网络与IO的优化,大家可以从以下几方面入手:
1、限制短时间内的发包率
2、合理优化包大小,减少包的冗余数据,降低网络请求次数
3、对回包进行分帧处理,及时响应
4、使用独立线程、协程等手段优化资源加载。
动态链接程序库,全称:Dynamic Link Library,简称:DLL,作用在于为应用程序提供扩展功能。应用程序想要调用DLL文件,需要跟其进行"动态链接";…
DLL后门原理及特点 把一个实现了后门功能的代码写成一个DLL文件,然后插入到一个EXE文件当中,使其可以执行,这样就不需要占用进程,也就没有相对应的PID号。…
你是指的是将嵌入html页面的unity3d文件作为独立软件运行吧?这个是不能独立运行的,如果要在单机上打开文件可以有下面几种方法:
将文件嵌入页面,如果你已经下载并安装了unitywebplayer插件,是可以离线打开页面的,如果你不想通过浏览器来看,那么这个方法可能不适合你;
用Visual Studio编写一个软件(用C#、VB、VC++各种语言都可以),在窗体中放一个WebBrowser控件,然后将WebBrowser控件的url属性设置为需要显示的页面文件(嵌入了unity3d文件)的路径,这样看起来就是一个独立的软件了。
原理同上,安装了unitywebplayer插件后,在窗体中放一个UnityWebPlayer Control控件(要添加COM组件到工具箱),将控件的src属性设为你需要显示的unity3d文件路径,这样也可以成为一个独立运行的软件,还可以通过组件的SendMessage方法与场景交互。效果如下:
这个是最彻底的,如果你有工程源码,重新发布成独立运行的软件就行了。
unity目前支持发布的平台还不包含微信小游戏,现在把unity开发的内容发布到微信小游戏平台是依赖微信提供的小游戏适配方案。本文主要介绍的是如何通过转换工具把unity项目转换成微信小游戏项目。

一、准备工作
1下载插件
进入微信提供的工具GitHub地址,找到安装与使用 – Unity插件, 也可直接点击下载,下载完成后是unitypackage的包:

2unity项目
确保项目的各项功能开发完整,没有Bug。unity编辑器需要安装好Web Gl模块能够正常导出网页版。
官方提示:转微信小游戏插件已验证Unity版本:2018、2019、2020、2021(请尽量使用LTS, 推荐使用2019、2021)。

3微信开发者工具
从微信开发者平台上找到微信开发者工具,并下载。
我使用的是微信开发者工具,不是《微信开发者工具(小游戏版 Minigame Build)》,不确定小游戏版是否能够正常使用。

4小游戏账号
在微信公众平台上注册一个小游戏号,每个邮箱仅能申请一个小程序,按照要求填写相关信息。确保最后能够拿到APPID。
注意:一定要有一个账号,因为后面需要开启微信开发者工具中的插件,如果没有的话导入unity的项目后不能正常打开。

在小程序页面中找到:成长/能力地图/生产提效包 在里面开启unity插件。

到此为止,工具以及准备完成,下面进行转换。
二、转换小游戏
unity导出小程序项目
1在unity编辑器中导入之前下载的转换工具unitypackage包。
2设置转换工具,主要是appid、项目名称、游戏方向、导出路径、资源加载方式。

3点击下方转换按钮,经过一段时间会在导出路径生成相关文件。
使用微信开发者工具发布
4打开微信开发者工具,首次使用需要用在微信公众平台注册过的微信扫描登录。
5导入unity转换的小游戏项目。

6在微信开发者工具中预览效果。
导入后编辑会报错,原因是需要下载一个插件,点击调试框内的插件下载。
点击预览可以生成一个短时间的二维码,微信扫码后可以在手机上运行(这里只能自己的微信可以打开);
点击上传,成功后,登录微信公众平台,管理—>版本管理—>开发版本设置成体验版。
以上就是关于【Unity】打包(二)全部的内容,包括:【Unity】打包(二)、unity脚本程序的输出和输入可以靠什么实现、Unity3D 学习路线等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)