Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条

异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务。在同步加载游戏场景的时候通常会使用方法 Application.LoadLevel(“yourScene”);  这句代码执行完毕后程序会干什么呢??如下图所示,这是我随便找了一个游戏场景, 在Hierarchy视图中我们可以看到该场景中“天生”的所有游戏对象。天生的意思就是运行程序前该场景中就已经存在的所有游戏对象。然后这些对象就会在执行完Application.LoadLevel(“yourScene”);方法后加载至内存当中。如果该场景中的游戏对象过多那么瞬间将会出现卡一下的情况,因为LoadLevel()方法是同步进行的。MOMO把这种加载起个名字叫A形式加载

下面我说说“后天“加载的游戏对象。意思是这些游戏对象是通过脚本动态的创建出来的。比如常用方法 :

1GameObject Obj = (GameObject)Instantiate(prefab);

这句代码执行完毕后同样会在Hierarchy视图中添加对应的游戏对象。MOMO把这种加载起个名字叫B形式加载。

下面我们学习异步加载游戏场景,异步异步顾名思义就是不影响当前游戏场景的前提下加载新场景。通常异步加载的方式分为两种:第一种是异步加载新游戏场景,当新场景加载完成后进入新场景并且销毁之前的场景。第二种:同样异步加载新场景,新场景加载完毕后,保留旧场景的游戏对象并且进入新场景。 这里加载的内容就是上面提到的A形式加载。然后B形式加载不会记入这里的加载。

第一种异步加载游戏场景对应的方法是:

1Application.LoadLevelAsync("yourScene");

第二种异步家在游戏场景对应的方法是:

1Application.LoadLevelAdditiveAsync ("yourScene");

这两种方法加载的方式�完全一样。异步加载其实重要还是应用于游戏LOADING界面,毕竟LOADING如果采用同步的机制会影响用户体验,说到这里MOMO告诉大家如何在Unity中制作游戏进度条。我们应当在Unity中创建一个专门用于读取进度的场景,假设A场景到C场景,我们应当让A场景先到读取进度的场景B场景,当异步任务完成后在进入C场景。 A – 》B -》 C ,在B场景中绘制游戏进度条或读取动画因为B场景仅仅是个显示LOADING动画的场景,所以读取该场景是瞬间就完成的。

程序在切换场景时应当有一个全全局的静态变量来记录简要读取的场景名称。这里简单的写一下。

1usingUnityEngine;

2usingSystem.Collections;

3

4publicclassGlobe

5{

6//在这里记录当前切换场景的名称

7publicstaticstringloadName;

8}

在A场景中通过某些触发条件 调用LoadLevel进入B场景。

1//记录LOADING场景中需要读取的C场景名称

2Globe.loadName ="C";

3//先进入B场景

4Application.LoadLevel ("B");

OK我们在B场景中异步读取C场景与 播放读取动画,Loading.cs 绑定在B场景的摄像机对象身上。当C场景异步读取完毕后即可直接进入C场景。

01usingUnityEngine;

02usingSystem.Collections;

03

04publicclassLoading : MonoBehaviour {

05

06privatefloatfps = 10.0f;

07privatefloattime;

08//一组动画的贴图,在编辑器中赋值。

09publicTexture2D[] animations;

10privateintnowFram;

11//异步对象

12AsyncOperation async;

13

14//读取场景的进度,它的取值范围在0 - 1 之间。

15intprogress = 0;

16

17voidStart()

18{

19//在这里开启一个异步任务,

20//进入loadScene方法。

21StartCoroutine(loadScene());

22}

23

24//注意这里返回值一定是 IEnumerator

25IEnumerator loadScene()

26{

27//异步读取场景。

28//Globe.loadName 就是A场景中需要读取的C场景名称。

29async = Application.LoadLevelAsync(Globe.loadName);

30

31//读取完毕后返回, 系统会自动进入C场景

32yieldreturnasync;

33

34}

35

36voidOnGUI()

37{

38//因为在异步读取场景,

39//所以这里我们可以刷新UI

40DrawAnimation(animations);

41

42}

43

44voidUpdate()

45{

46

47//�在这里计算读取的进度,

48//progress 的取值范围在0.1 - 1之间, 但是它不会等于1

49//也就是说progress可能是0.9的时候就直接进入新场景了

50//所以在写进度条的时候需要注意一下。

51//为了计算百分比 所以直接乘以100即可

52progress =  (int)(async.progress *100);

53

54//有了读取进度的数值,大家可以自行制作进度条啦。

55Debug.Log("xuanyusong"+progress);

56

57}

58//这是一个简单绘制2D动画�的方法,没什么好说的。

59voidDrawAnimation(Texture2D[] tex)

60{

61

62time += Time.deltaTime;

63

64if(time >= 1.0 / fps){

65

66nowFram++;

67

68time = 0;

69

70if(nowFram >= tex.Length)

71{

72nowFram = 0;

73}

74}

75GUI.DrawTexture(newRect( 100,100,40,60) ,tex[nowFram] );

76

77//在这里显示读取的进度。

78GUI.Label(newRect( 100,180,300,60),"lOADING!!!!!"+ progress);

79

80}

81

82}

OK 下面我们继续学习在游戏场景中加载对象,文章的开始MOMO已经告诉大家,游戏场景中Hierarchy视图中的所有的对象在切换场景的时候都会加载。其实有一种方法可以让某些游戏对象不会被加载,如下图所示,首先在Hierarchy视图中选择一个游戏对象,在右侧监测面板视图中我们可以看到一个 “小对勾”默认情况下是勾选状态,说明该游戏对象处于激活状态,如果点掉的话该对象将被隐藏。这个小功能在开发中其实用处非常大,请大家务必记住哈。

此时此刻大家相像一个游戏场景,默认进入的时候是没有任何游戏对象的,然后运行游戏时开启一个异步任务将它们一个一个的加载显示出来,这种方式适合异步的加载一个比较大的游戏场景。

Test.cs 把它挂在摄像机对象中。

01usingUnityEngine;

02usingSystem.Collections;

03

04publicclassTest : MonoBehaviour {

05

06//这里是需要加载激活的游戏对象

07publicGameObject  [] Objects;

08

09//当前加载的进度

10intload_index =0;

11voidStart ()

12{

13//开启一个异步任务,加载模型。

14StartCoroutine(loadObject());

15}

16

17IEnumerator loadObject()

18{

19//便利所有游戏对象

20foreach(GameObject objinObjects)

21{

22//激活游戏对象

23obj.active =true;

24//记录当前加载的对象

25load_index ++;

26

27//这里可以理解为通知主线程刷新UI

28yieldreturn0;

29}

30//全部便利完毕返回

31yieldreturn0;

32}

33

34voidOnGUI ()

35{

36//显示加载的进度

37GUILayout.Box("当前加载的对象ID是: "+ load_index);

38}

39}

如下图所示,我们把需要加载的游戏对象以数组的形式放在Objects数组中,因为这些对象属于未激活状态,所以不能通过Find 等方法在�脚步那种中找到他们。讲到这里我们在说说 编辑器赋值与代码中赋值的区别,编辑器中赋值所消耗的时间都会记在loadlevel ()读取场景中。而代码中使用Resource.load()这类方法所消耗的时间会记在脚本中。开发中还得自行的把握一下把loading加在那里。

当然我们还可以使用Instantiate(prefab);方法来动态的创建游戏对象。

Main.cs 把它挂在摄像机中。

01usingUnityEngine;

02usingSystem.Collections;

03

04publicclassMain : MonoBehaviour

05{

06

07publicintcount;

08//在编辑器中预设一个游戏对象

09publicGameObject prefab;

10

11voidStart ()

12{

13StartCoroutine(loaditem());

14}

15

16voidOnGUI()

17{

18GUILayout.Box("游戏对象已经加载到 : "+ count);

19}

20

21IEnumerator loaditem()

22{

23//开始加载游戏对象

24for(inti =0; i< 1000; i++)

25{

26

27Instantiate(prefab);

28count = i;

29//可以理解为刷新UI,显示新加载的游戏对象

30yieldreturn0;

31}

32//结束

33yieldreturn0;

34}

35}

运行游戏后该游戏对象会循环1000遍逐个创建,不影响主线程。那么今天我们其实学习最多的就是StartCoroutine(),其实就是开启一个异步线程,这里可能有朋友会问Thread可以代替它吗? 答案是不行, 比如查询数据库的时候如果用Thread的话Unity就会报错说不能在线程中查询,但是在StartCoroutine()中就可以完成,所以开发中大家可以尝试着使用它,我们还可以使用StopCoroutine(“name”)来关闭一个正在执行的异步线程。不早了晚安,MOMO祝大家学习愉快。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,051评论 25 707
  • 背景 通常游戏的主场景包含的资源较多,这会导致加载场景的时间较长。为了避免这个问题,可以首先加载Loading场景...
    胤醚貔貅阅读 2,350评论 0 3
  • 等着你 翠滴轻落入泥 宛若你脚步轻移 伫立窗台不肯离去 远望黑云渐渐散去 等七彩祥云飘来 我踏上北去 见你抱你 不...
    定格不留白阅读 191评论 0 0
  • 第一天画、感觉图阴影好难! 明天继续加油!
    biubiu_嘿宝阅读 283评论 0 1
  • 灯光骤亮 返场 掌声潮涌 谢幕。 深鞠一躬 灵魂从那一处 回到这一处 兴奋 又恍惚。 我是谁? 谁谢幕? 是大幕将...
    王子魚阅读 484评论 5 8