unity制作进度条在unity 异步加载场景小场景时没有问题,但是在大场景时会出现问题

Unity3d中制作Loading场景进度条所遇到的问题
通常游戏的主场景包含的资源较多,这会导致加载场景的时间较长。为了避免这个问题,可以首先加载Loading场景,然后再通过Loading场景来加载主场景。因为Loading场景包含的资源较少,所以加载速度快。在加载主场景的时候一般会在Loading界面中显示一个进度条来告知玩家当前加载的进度。在Unity中可以通过调用Application.LoadLevelAsync函数来异步加载游戏场景,通过查询AsyncOperation.progress的值来得到场景加载的进度。
尝试——遇到问题
第一步当加载完Loading场景后,调用如下的LoadGame函数开始加载游戏场景,使用异步加载的方式加载场景1(Loading场景为0,主场景为1),通过Unity提供的Coroutine机制,我们可以方便的在每一帧结束后调用SetLoadingPercentage函数来更新界面中显示的进度条的数值。
public void LoadGame() {
StartCoroutine(StartLoading_1(1));
private IEnumerator StartLoading_1(int scene) {
AsyncOperation op = Application.LoadLevelAsync(scene);
while(!op.isDone) {
SetLoadingPercentage(op.progress * 100);
yield return new WaitForEndOfFrame();
最后进度条的效果显示如下:
进度条并没有连续的显示加载的进度,而是停顿一下切换一个数字,再停顿一下切换一个数子,最后在没有显示100%就情况下就切换到主场景了。究其原因在于Application.LoadLevelAsync并不是真正的后台加载,它在每一帧加载一些游戏资源,并给出一个progress值,所以在加载的时候还是会造成游戏卡顿,AsyncOperation.progress的值也不够精确。当主场景加载完毕后Unity就自动切换场景,所以上述代码中的while循环体内的代码是不会被调用的,导致进度条不会显示100%。
修补——100%完成
为了让进度条能显示100%,取巧一点的办法是将AsyncOperation.progress的值乘上2,这样当加载到50%的时候界面上就显示100%了。缺点是当界面上显示100%的时候,用户还要等待一段时间才会进入游戏。其实Unity提供了手动切换场景的方法,把AsyncOperation.allowSceneActivation设为false就可以禁止Unity加载完毕后自动切换场景,修改后的StartLoading_2代码如下:
// this function is not work
private IEnumerator StartLoading_2(int scene) {
AsyncOperation op = Application.LoadLevelAsync(scene);
op.allowSceneActivation = false;
while(!op.isDone) {
SetLoadingPercentage(op.progress * 100);
yield return new WaitForEndOfFrame();
op.allowSceneActivation = true;
我们首先将AsyncOperation.allowSceneActivation设为false,当加载完成后再设为true。代码看上去没有错,但是执行的结果是进度条最后会一直停留在90%上,场景不会切换。通过打印log发现AsyncOperation.isDone一直为false,AsyncOperation.progress的值增加到0.9后就保持不变了,也就是说场景永远不会被加载完毕。
在这个帖子中找到了答案,原来把allowSceneActivation设置为false后,Unity就只会加载场景到90%,剩下的10%要等到allowSceneActivation设置为true后才加载,这不得不说是一个坑。所以代码改为如下。当AsyncOperation.progress到达0.9后,就直接把进度条的数值更新为100%,然后设置AsyncOperation.allowSceneActivation为ture,让Unity继续加载未完成的场景。
private IEnumerator StartLoading_3(int scene) {
AsyncOperation op = Application.LoadLevelAsync(scene);
op.allowSceneActivation = false;
while(op.progress & 0.9f) {
SetLoadingPercentage(op.progress * 100);
yield return new WaitForEndOfFrame();
SetLoadingPercentage(100);
yield return new WaitForEndOfFrame();
op.allowSceneActivation = true;
最后的效果如下:
打磨——增加动画
上述的进度条虽然解决了100%显示的问题,但由于进度条的数值更新不是连续的,所以看上去不够自然和美观。为了看上去像是在连续加载,可以每一次更新进度条的时候插入过渡数值。这里我采用的策略是当获得AsyncOperation.progress的值后,不立即更新进度条的数值,而是每一帧在原有的数值上加1,这样就会产生数字不停滚动的动画效果了,迅雷中显示下载进度就用了这个方法。
private IEnumerator StartLoading_4(int scene) {
int displayProgress = 0;
int toProgress = 0;
AsyncOperation op = Application.LoadLevelAsync(scene);
op.allowSceneActivation = false;
while(op.progress & 0.9f) {
toProgress = (int)op.progress * 100;
while(displayProgress & toProgress) {
++displayProgress;
SetLoadingPercentage(displayProgress);
yield return new WaitForEndOfFrame();
toProgress = 100;
while(displayProgress & toProgress){
++displayProgress;
SetLoadingPercentage(displayProgress);
yield return new WaitForEndOfFrame();
op.allowSceneActivation = true;
displayProgress用来记录要显示在进度条上的数值,最后进度条的动画如下:
对比第一种的进度条
如果在加载游戏主场景之前还需要解析数据表格,生成对象池,进行网络连接等操作,那么可以给这些操作赋予一个权值,利用这些权值就可以计算加载的进度了。如果你的场景加载速度非常快,那么可以使用一个假的进度条,让玩家看上几秒钟的loading动画,然后再加载场景。总之进度条虽然小,但要做好也是不容易的。
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!豆丁微信公众号
君,已阅读到文档的结尾了呢~~
unity3d学习之异步加载游戏场景与异步加载游戏资源进度条,jquery 加载进度条,加载进度条,android加载进度条,网页加载进度条,html 加载进度条,异步加载,ztree 异步加载,ios异步加载图片,js异步加载
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
unity3d学习之异步加载游戏场景与异步加载游戏资源进度条
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='http://www.docin.com/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口unity 场景的异步加载怎么显示进度条_百度知道
unity 场景的异步加载怎么显示进度条
我有更好的答案
新建两个场景,保存为level1和level22.将图片素材放进工程文件中,分别作为关卡背景、进度条背景和进度条前景3.创建C#脚本,取名Life4.打开脚本,加入如图所示代码5.将脚本拖拽到摄像机上,将三张图片对号入座到图片变量中6.按播放键调试
采纳率:70%
来自团队:
为您推荐:
其他类似问题
您可能关注的内容
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。程序丨如何解决Unity3D场景加载中出现的问题?
译者:崔嘉艺(milan21)
审校:崔国军(飞扬971)
为什么会想要和大家说说Unity3D中加载场景,主要是因为在项目的场景中经常会出现一些问题,所以在这里就想和大家分享一些加载场景的想法。
你如何对一个“关卡”进行编程?
这在游戏引擎中通常不是一个问题,但Unity需要你将每个“关卡”隔离为一个场景。并且Unity的场景有一些奇怪的设计选择(或者就是bug?) - 感觉他们引擎的场景是为玩具项目设计的,而不是为产品级别的游戏所设计。
这里有一个什么起作用、什么不起作用、以及我如何解决/在Unity内做得更好的意识流。。。这些内容没有经过仔细研究,大多是来自记忆或我自己的拍脑袋。 所以。。。这篇文章里面记录的内容可能不是全部是真的:)。
当我切换到Unreal4的时候,我将使用这样的帖子作为基准来比较Unity为什么会失败,以及多么糟糕 - 反之亦然。
更新:我添加了更多的方法和想法/评论
举个简单的例子来说:
1.加载场景的时候,游戏中的所有内容都将被销毁。
2.场景不能带参数。
3.场景不能保留状态。
4.场景不能在代码中构造或是修改。 程序化的游戏? 哈哈! 根本没有机会!
5.你不能一次编辑多个场景(这是荒谬的,给开发带来不必要地痛苦)。
6. 。。。和一堆其他问题,其中许多问题是上述问题的副作用。
更多Unity的bug使得你在处理这个问题的时候感觉像是在地狱里
1.当场景加载的时候,没有办法告诉Unity要运行什么代码。
o这是必需的,因为Unity拒绝让你传递参数。
o因为没有办法传递参数,所以你必须依赖Awake(),Start()和OnEnable()方法。
o这三种方法被定义为在对象之间以“随机”的顺序进行运行。
o如果你有一个需要被查找、加载和定位的参数,可以将其放在Awake()函数之中。
o如果需要对这个参数做全局引用,则必须在Start()函数运行期间设置它,否则不能保证它已被找到。
o任何需要使用该参数的代码都不能写在OnEnable()之外的其他方法中。
o。。。但是:很多(绝大多数?)理应在Start()方法中的代码,如果写在OnEnable()中就不能正常工作了,因为Start()和OnEnable()这两个方法做的是不同的事情!
Unity的场景加载太烦人了。
一些常见的解决方法
Unity5:增量加载
你可以加载一个场景,然后在这个的基础之上加载另一个场景。在某种程度上这个功能在UnityPro中一直存在(比如允许“关卡加载器”的场景等等),但是Unity5对这一点进行了升级和扩展。
根据我的理解,Unity5并没有解决这些问题,但它确实减轻了这些问题。 特别是,我已经看到了编辑器的修改记录,以改善一次加载多个场景的处理。但我自己还没有尝试过这块(我还使用Unity4的版本)。从我看过的视频来看,它看起来像是一个明确的改进,但距离我称之为“标准”的游戏引擎仍然有相当长的一段时间。
如果你能使用Unity5,请看看你可以走多远。然后把有关你的提示和技巧通过推特发给我。
不要选择“在加载的时候删除一切(DontDestroy)”
你可以标记任意数量的游戏物体为“嘿,Unity! 当你删除一切(这是愚蠢的主意,但是可行)的时候,请不要删除这些游戏物体!
在理论上,这意味着你可以编写自己的迷你游戏引擎(你为什么要再次使用Unity,因为你一直想重新发明轮子,对吗?),然后把所有的游戏数据存储为一个“不要销毁”的对象,然后在新场景完成加载后解析并加载刚才那个“不要销毁”的对象。
这不解决任何问题-它只是将问题转移到一个新的地方,但至少它们现在是在你的代码中进行处理,而不是在Unity的代码中进行处理。你最终会写自己的迷你游戏引擎。你从Unity获得的是几乎零帮助,并。。。使这个问题更难。。。你必须保持与Unity的专有数据处理的兼容:初始化协议,蹩脚的序列化等等。
这是做“不要在加载的时候删除一切(DontDestroy)”的“真正的”方式,“不要在加载的时候删除一切(DontDestroy)”是内置于编程语言的标准方法。 它让我觉得奇怪的是,Unity在有了一个更标准的方法以后,还添加了“不要在加载的时候删除一切” 是不是一个初级程序员谁不知道如何使用“静态”关键字?还是有一些令人讨厌的埋在Unity核心引擎的东西打破了静态? (提示:我几乎可以保证它会是序列化系统中的某个地方的一个bug,我很讨厌这一点,如果你还没有注意到的话)。 在Unity的架构中几乎所有的东西都会与那个怪物打交道!)
它似乎对我来说总是工作正常。但它是可怕的:它什么时候会停止工作? 你怎么才能知道这一点? 有什么Unity的bug潜伏在这里?
自包含的场景
拿掉所有的游戏逻辑,我们已经把数据作为参数传递给了你的场景(在任何正常的引擎中)。。。而不是将参数嵌入在场景之内。
当场景加载的时候,它运行这个逻辑,然后发现“哦! 我似乎缺少很多核心数据。我最好在运行的过程重新创建它!
这是一个曲折的逻辑,对那些新加入你的团队的开发者来说可能非常混乱(并且也可能混乱到了你自己,如果你从项目中休息了一段时间再回来)。但它有一些显著的好处:
你可以在游戏中运行场景。。。或。。。直接从Unity编辑器运行它,它将表现的(几乎)相同。可以以这种方式进行更快的测试+调试
场景保持着自包含的特点。 这是Unity的设计师“打算”你使用场景(虽然这对于游戏来说是一个非常糟糕的解决方案)的方式。 这对你的游戏的源代码控制和多用户编辑有一些微小的好处:如果你这样工作的话,你会遇到少量的Unity核心bug。
理论上:更多的“场景特定”的代码位于场景中(在Unity编辑器中)。当你的项目变大的时候,在理论上:这使得理解发生了什么更容易,因为代码+对象对于彼此都是本地局部的。我不完全确认这一点:与Unity那种比较差的安排代码+数据的方式相比。。。在实践中,这个局部性可能不明显(Unity编辑器“隐藏”了局部性,所以你作为开发人员并没有从中得到什么好处)。
使用预制件(Prefabs)
好吧,我遇到过那些声称这样做的人-在编辑器中创建场景,然后将所有内容转换为预制件,然后在场景加载的时候加载预制件,传递不同的“要加载的预制件的名字”列表。
哦,请不要这么做!
首先:Unity中的预制件对于这种复杂的情况会被严重破坏。他们不能正常工作,你应该尽可能避免使用预制件-除了那些最简单的用例(非嵌套、简单的小预制件)。
第二:哇,这很曲折。 你正在滥用“模板化的对象系统”来绕过“数据层”和“场景加载器”中的设计缺陷。它可能是一种天才做法-但它是那种不寻常的天才做法,它很容易在未来的更新后的引擎被破坏,而Unity可以合法地说:“嗯?你为什么要这样做?“
如果它在你的项目中正常工作,这太棒了! 但对我来说,这总是一个隐患。可能我错过了一些好的做法,这可能是一个比我意识到的更好的路线。在大多数情况下,这是事实,Unity不能处理正确复杂的预制件是事实。Unity5据称修复了一些预制件方面的错误,所以。。。我会在某个时候再考虑使用预制件。然而,Unity中的预制件方面的历史是非常丑陋的,我会非常谨慎的信任他们。
这些问题的解决方法
Unity不支持字典和哈希表
这是一个巨大的散发着臭味的问题(纵观整个Unity的历史!)。
它改变了上述解决方法中的利弊平衡。你不能简单地添加命名参数到你的静态方法和 “不要在加载的时候删除一切”的列表中-因为Unity会穿过编程语言来直接删除/销毁/损坏它们。
(我说过我讨厌Unity的破天荒的序列化系统吗?好吧,我非常讨厌这个系统)。
最后,我发现“不要在加载的时候删除一切(DontDestroy)”最有吸引力的部分是你可以使用:
GameObject param1 = ... ;
GameObject persistentObject = ... ;
param1.transform.parent = persistentObject.
//param1.tag = ... oh, no - can't do this. Unity's tags are hardcoded (that is NOT what Tag means, guys!)
param1.name = "Parameter 1";
然后,你可以使用类似以下的内容来对它进行检索:
GameObject persistentObject = ... ;
GameObject param1 = persistentObject.Find( "Parameter 1" );
(假设你不知何故得到了一个持久对象的引用。。。举个简单的例子来说,使它成为一个单例)。
我相信你也可以使用静态对象来做到这一点(?)但是。。。把一整个对象关系图隐藏在一个静态成员变量里面可能会进入“这可能会暴露Unity序列化的Bug”的领域。 最好避免这么做:不要浪费太多的时间在调试Unity上。
理想/正确的解决方案
数据就是数据
我们回到那个Unity中反复出现的问题,它对引擎的破坏这么大:Unity拒绝承认“数据”就是“数据”。 它坚持:“不,不! 数据是代码和对象还有图形和物理对象以及。。。和。。。和。。。和。。。“。
(让我们澄清一点:有经验的程序员看不起Unity的方法,而且一般都是非常尖刻不留情。这不是因为我们对其他引擎和方法狂热- 而是Unity的编程方法在20世纪80年代就基本上死了。它没有做什么限制,很快就被证明很难创建复杂的程序比如说是视频游戏)。
理想情况下,我们会将游戏的数据存储为数据,并在加载的时候将数据传递给场景。 Unity阻止我们这样做。我们为模拟这一切而做的一切(例如嵌入JSON(反)序列化器)是搬掉Unity路障的解决方法。
当前的实验
我已经在以前的Unity项目中尝试了大多数以上的方法,没有一个做得特别好。
这次尝试什么?
这里是我目前的需求:
1.当场景加载的时候,我需要注入玩家角色。这是一个复杂的对象,包括渲染、物理和程序化网格。
2.当场景加载的时候,我需要单独配置一些不可见的状态:比如玩家的特征(例如命中点、得分)。。。这些不可见的状态关卡会克隆并用作可见状态(在关卡变化期间的命中点。当你开始一个关卡时候的命中点会“保存”那些不变的值)。
3.当场景加载的时候,。。。我也有不可见的状态,用于生成其他状态。举个简单的例子来说,关于到目前为止已经探索了这个关卡多少的信息、 战争迷雾等等。
4.当玩家完成关卡的时候,我需要选择一些数据保存到主菜单,并保存到磁盘中。
5.当玩家完成关卡的时候,我需要存储“之前”和“之后”之间的差异,以便我可以授予各种徽章/成就和一次性奖励等等。此外,以便我可以展示“ 这是你已经实现的成就!“的最终结束界面。
我已经放弃了:我写了一个自己的迷你引擎来解决Unity可怕的场景管理。回顾我的许多Unity项目,我已经用了很多天,可能超过一个星期,不得不不断地重新实现这个核心功能,因为Unity版本的场景管理情况令人难以置信的混乱。
这是诸多bug的其中一个,就是这些bug让我认为Unity的技术负责人从来不自己写游戏。如果他们这样自己写游戏的话,他们不会忍受这种渣问题的。
简短的描述:
每次场景开始加载的时候,写一个类加载钩子(使用C#)。
调试Unity加载场景的时候所有正式文档之外的API调用。这可能需要很长时间。
做反向工程来知道Unity场景的哪些部分是“有效”和何时“有效”。
编写每个商业游戏引擎(Unity除外!)用于管理场景加载的那种代码。
将其包装在API中。
永远不要在Unity的场景系统里面再处理这个问题,永远永远都不要!
有用的功能
对两个游戏物体进行“比对”寻找差异化
这将是非常有用的。这将使得上面的许多解决方法更加容易。
这个功能也内置于Unity之中。我们知道这一点:序列化系统依赖于这个功能。
但是他们不允许我们访问(就我所知:我没有看到一个公共API会去调用这个功能)。
“克隆”一个游戏物体,保持对原始游戏物体的引用
所有面向对象编程语言的对象(包括C#)会跟踪它们所创建的类。
如果Unity再次使用“clone object1 to create object2”来做同样的事情,这将使许多上面的方法更加容易,也更加不容易出错。
【版权声明】
原文作者未做权利声明,视为共享知识产权进入公共领域,自动获得授权。
1.加入GAD程序猿交流基地
获取行业干货资讯,观看大牛分享直播
2.直接领取60G独家程序资料库,地址在小编朋友圈
包括腾讯内部分享、文章教程、视频教程等全套资料
责任编辑:
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
专业游戏开发社区
服务广大游戏开发者,为开发者们解决游戏开发中的难题
今日搜狐热点unity游戏场景资源加载进度条Loading Screens,Unity3D,游戏源码,6m5m游戏素材
请求处理中...
unity游戏场景资源加载进度条Loading Screens for Mad Level Manager ,5种预制进度条样式,自动计算加载时间,支持uGUI和NGUI,可定制强,并且有个等待中与玩家互动的功能,大家自己研究下。
或 0 积分 ()
下载561浏览人数6613交付方式直接下载
免责声明:【1】资源来自网络,仅限于个人学习研究,请勿用于任何商业用途,请支持或购买正版,尊重版权,请严格遵守国家相关著作版权保护的法律和规则,请下载24小时内务必删除,否则后果自负,本站不承担任何责任及连带责任!【2】本站为学习平台,所分享的资源以学习为目的,并不能保证所有源码人人都能编译,因素太多,旨在学习参考,无任何技术支持,如果您要求完美或追求细节,请勿下载,大家都不容易,互相理解,才能让更多好的学习资源出现!【3】部分素材压缩包因体积过大而上传到百度等网盘上,如果发现在本站下载的压缩包只要有几K大小,说明该压缩包里只是网盘的下载链接,并非文件损坏,本站的所有素材都是经过了审核,大家可放心下载,欢迎监督反馈。【4】做个好平台真心不容易,我们一直在努力,因本站素材量大,难免会出现某网盘下载链接失效等问题,请大家及时反馈,我们会及时修正保证您可以拿到素材,请大家支持和理解!
免责声明:本网所展示的素材与服务信息由买卖双方自行提供,其真实性、准确性和合法性由信息发布人负责。本网不提供任何保证,并不承担任何法律责任,如有不妥之处请及时反馈,本网将会妥善处理。
友情提醒:本站旨在游戏开发的学习,所分享的素材资源均来源于网络,仅适用于学习参考,尊重版权,禁止用于任何商业用途,否则后果自负,所展示的素材版权归原作者或公司所有,如果本站素材侵犯了您的权益,请联系我们,我们将及时处理。
猜您喜欢的游戏素材
0金币 / 份
1金币 / 个
1金币 / 个
0金币 / 个
1金币 / 个
0金币 / 个
0金币 / 个
2金币 / 个
0金币 / 个
1金币 / 个
好评率99.87%
发布素材52

我要回帖

更多关于 unity 重新加载场景 的文章

 

随机推荐