http://www.xuanyusong.com/archives/1427

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

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

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

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

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

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

1 Application.LoadLevelAsync("yourScene");

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

1 Application.LoadLevelAdditiveAsync ("yourScene");

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

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

1 using UnityEngine;
2 using System.Collections;
3  
4 public class Globe
5 {
6          //在这里记录当前切换场景的名称
7      public static string loadName;
8 }

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

1 //记录LOADING场景中需要读取的C场景名称
2 Globe.loadName = "C";
3 //先进入B场景
4 Application.LoadLevel ("B");

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

01 using UnityEngine;
02 using System.Collections;
03  
04 public class Loading : MonoBehaviour {
05  
06     private float fps = 10.0f;
07     private float time;
08     //一组动画的贴图,在编辑器中赋值。
09     public Texture2D[] animations;
10     private int nowFram;
11     //异步对象
12     AsyncOperation async;
13  
14     //读取场景的进度,它的取值范围在0 - 1 之间。
15     int progress = 0;
16  
17     void Start()
18     {
19         //在这里开启一个异步任务,
20         //进入loadScene方法。
21         StartCoroutine(loadScene());
22     }
23  
24     //注意这里返回值一定是 IEnumerator
25     IEnumerator loadScene()
26     {
27         //异步读取场景。
28         //Globe.loadName 就是A场景中需要读取的C场景名称。
29         async = Application.LoadLevelAsync(Globe.loadName);
30  
31         //读取完毕后返回, 系统会自动进入C场景
32         yield return async;
33  
34     }
35  
36     void OnGUI()
37     {
38         //因为在异步读取场景,
39         //所以这里我们可以刷新UI
40         DrawAnimation(animations);
41  
42     }
43  
44     void Update()
45     {
46  
47         //在这里计算读取的进度,
48         //progress 的取值范围在0.1 - 1之间, 但是它不会等于1
49         //也就是说progress可能是0.9的时候就直接进入新场景了
50         //所以在写进度条的时候需要注意一下。
51         //为了计算百分比 所以直接乘以100即可
52         progress =  (int)(async.progress *100);
53  
54         //有了读取进度的数值,大家可以自行制作进度条啦。
55         Debug.Log("xuanyusong" +progress);
56  
57     }
58     //这是一个简单绘制2D动画的方法,没什么好说的。
59     void   DrawAnimation(Texture2D[] tex)
60     {
61  
62         time += Time.deltaTime;
63  
64          if(time >= 1.0 / fps){
65  
66              nowFram++;
67  
68              time = 0;
69  
70              if(nowFram >= tex.Length)
71              {
72                 nowFram = 0;
73              }
74         }
75         GUI.DrawTexture(new Rect( 100,100,40,60) ,tex[nowFram] );
76  
77         //在这里显示读取的进度。
78         GUI.Label(new Rect( 100,180,300,60), "lOADING!!!!!" + progress);
79  
80     }
81  
82 }

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

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

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

01 using UnityEngine;
02 using System.Collections;
03  
04 public class Test : MonoBehaviour {
05  
06     //这里是需要加载激活的游戏对象
07     public GameObject  [] Objects;
08  
09     //当前加载的进度
10     int load_index =0;
11     void Start ()
12     {
13         //开启一个异步任务,加载模型。
14         StartCoroutine(loadObject());
15     }
16  
17     IEnumerator loadObject()
18     {
19         //便利所有游戏对象
20         foreach(GameObject obj in Objects)
21         {
22             //激活游戏对象
23             obj.active = true;
24             //记录当前加载的对象
25             load_index ++;
26  
27             //这里可以理解为通知主线程刷新UI
28             yield return 0;
29         }
30         //全部便利完毕返回
31         yield return 0;
32     }
33  
34     void OnGUI ()
35     {
36         //显示加载的进度
37         GUILayout.Box("当前加载的对象ID是: " + load_index);
38     }
39 }

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

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

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

01 using UnityEngine;
02 using System.Collections;
03  
04 public class Main : MonoBehaviour
05  {
06  
07     public int count;
08     //在编辑器中预设一个游戏对象
09     public  GameObject prefab;
10  
11     void Start ()
12     {
13         StartCoroutine(loaditem());
14     }
15  
16     void OnGUI()
17     {
18         GUILayout.Box("游戏对象已经加载到 : " + count);
19     }
20  
21     IEnumerator loaditem()
22     {
23         //开始加载游戏对象
24         for(int i =0; i< 1000; i++)
25         {
26  
27             Instantiate(prefab);
28             count = i;
29             //可以理解为刷新UI,显示新加载的游戏对象
30             yield return 0;
31         }
32         //结束
33         yield return 0;
34     }
35 }

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

(转)Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)的更多相关文章

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

    Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条 异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Ap ...

  2. (转)Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)

      异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Application.LoadLevel(“yourScene ...

  3. 【Unity3d】3d网页游戏场景打包与加载

    http://www.cnblogs.com/dosomething/archive/2012/04/07/2436353.html 3d游戏中  一个场景往往比较大  如果游戏的进行需要下载一个10 ...

  4. 实现加载Tomcat服务器中的图片,并且有进度条提示进度

    首先布局页面, <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...

  5. [Unity3D]Unity3D游戏开发之异步记载场景并实现进度条读取效果

    大家好,我是秦元培.欢迎大家关注我的博客,我的博客地址是:blog.csdn.net/qinyuanpei.终于在各种无语的论文作业中解脱了,所以立即抓紧时间来这里更新博客.博主本来计划在Unity3 ...

  6. Unity 异步加载 进度条

    当我们进行游戏开发时,时常会进行场景切换,如果下个场景较大,切换时就会出现卡顿现象,甚至看起来像是"死机",非常影响用户体验,我们这时就可以运用异步加载,在界面上显示加载的进度条以 ...

  7. Unity3D_异步加载场景(进度条)

    创建两个场景:现在的场景“NowScene”,要加载的场景“LoadScene”: “NowScene”如图所示,“LoadScene”任意: 创建脚本“AsyncLoadScene”,复制如下代码, ...

  8. (转)Unity3D研究院之游戏架构脚本该如何来写(三十九)

     这篇文章MOMO主要想大家说明一下我在Unity3D游戏开发中是如何写游戏脚本的,对于Unity3D这套游戏引擎来说入门极快,可是要想做好却非常的难.这篇文章的目的是让哪些已经上手Unity3D游戏 ...

  9. Defender Game 游戏实践(1) 基本游戏场景实现

    在网上看到 郑州|boy 这个博客,里面有几篇文章,记录了其用cocos2d-x这个游戏引擎编写的一个游戏,十分不错,所以这段时间,依样画葫芦,依次学习一下. 由于博主开发的平台是在win32,而且屏 ...

随机推荐

  1. Linux & Windows 查看 ip 地址

    Windows 查看本机 IP 打开 cmd,输入 ipconfig,回车,找到IPv4地址 或者通过以下方式查看 点击Win10系统的右下角的宽带连接图标,如下图所示.        点击弹出菜单的 ...

  2. UEFI

    UEFI,全称Unified Extensible Firmware Interface,即“统一的可扩展固件接口”,是一种详细描述全新类型接口的标准,是适用于电脑的标准固件接口,旨在代替BIOS(基 ...

  3. SpringBoot Rabbitmq发送消息

    官方文档:https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-amqp ...

  4. 实用JS系列——面向对象中的类和继承

    背景: 在最开始学习JavaScript时,我们就知道,它是一种脚本语言,也有面向对象机制.但它的面向对象继承机制是基于原型的,即Prototype.今天,我们就来找一下JS中OO的影子. 创建类 1 ...

  5. PHP文件操作函数及文件指针理解

    知识点: 一.fopen(),文件打开函数,读写参数有: 1.R  : 只读,指针在文件开头 2.r+:读写,指针同上 3.W :只写,写入前会删除文件内容,然后指针回到文件开头,文件不存在则创建 4 ...

  6. 【bzoj5015】[Snoi2017]礼物 矩阵乘法

    题目描述 热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1-N,每个到来的朋友都会带给他一些礼物:.其中,第一个朋友会带给他 1 个,之后,每一个朋友到来以后,都会带给他之前所有人带来的礼物个数再 ...

  7. Gym100286C Clock

    不想打题面,题面戳这里. 被这题吓到了,感觉无从下手.最后还是看着题解和别人的代码加以改编最后写出了的.其实理解之后写出了也就是三四十行的样子了. 首先题目有个很重要的条件--转动某个针只会对周期比他 ...

  8. vue数组对象修改触发视图更新

    直接修改数组元素是无法触发视图更新的,如 this.array[0] = { name: 'meng', age: 22 } 修改array的length也无法触发视图更新,如 this.array. ...

  9. myeclipse maven web项目配置

    启用maven:window-->preference-->MyEclipse-->Maven4MyEclipse, 勾选复选框(Enable Mave4MyEclipse feat ...

  10. Gradle for Android(二)全局设置、自定义BuildConfig

    全局设置 如果有很多项目,可以设置全局来统一管理版本号或依赖库,根目录下build.gradle下: ext { compileSdkVersion = 23 buildToolsVersion = ...