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

异步任务相信大家应该不会陌生,那么本章内容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”)来关闭一个正在执行的异步线程。

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

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

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

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

    http://www.xuanyusong.com/archives/1427  异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通 ...

  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. Unity3D_异步加载场景(进度条)

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

  7. Unity 异步加载 进度条

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

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

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

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

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

随机推荐

  1. Swing的设计是MVC的典范

    无论你的项目是否用到了Swing技术,我都要说,Swing是一个设计优秀的Java包,它充满了大师的智慧.假设你学了Java却连一个Button还不会写,就象你学习Visual Basic却不会用Bu ...

  2. 我的docker 使用笔记

    0 容器启动 docker run image_name(镜像名称) echo "hello word" 1 启动容器 退出后 重新进入 方法一 sudo docker exec ...

  3. 再回首,Java温故知新(一):Java概述

    Java发展历程 Java的发展要追溯到1991年,Patrick Naughton(帕特里克·诺顿)和James Gosling(詹姆斯·高斯林)带领Sun公司的工程师打算为有线电视转换盒之类的消费 ...

  4. 使用AVCaptureSession捕捉静态图片

    #import <UIKit/UIKit.h> #import <AVFoundation/AVFoundation.h> #import <AssetsLibrary/ ...

  5. gridview实现表格编辑功能

    .net开发者对gridview应该非常熟悉,数据展现.数据编辑.数据删除,这些gridview都能很好的完成.最近在做东西的时候遇到 这样的一个需求,就是利用gridview实现类似Excel一样直 ...

  6. 关于ajaxfileupload.js一些问题和上传图片就立即显示图片功能

    ajaxfileupload.js是上传文件的一个插件,最近碰到的一个问题是在谷歌浏览器上传文件之后,原文本框中的文件名称消失,网上搜了好长时间也没有十分满意的答案.无刷新上传文件我想到的只有ajax ...

  7. DOM - nodeType 的取值

    DOM 中,共有 12 中不同类型的节点,nodeType 的取值以数值表示. 节点类型 描述 子节点 1  Element  表示元素.  Element, Text, Comment, Proce ...

  8. c读mysql产生乱码问题

    在编写接口API时,发现中文字utf8输入的在linux下采用c读取显示为”??”问号,这是由于编码造成的. 很简单的两个地方做修改就搞定. 1.先找到mysql的my.cnf配置文件/etc/my. ...

  9. Android布局管理器(线性布局)

    线性布局有LinearLayout类来代表,Android的线性布局和Swing的Box有点相似(他们都会将容器里面的组件一个接一个的排列起来),LinearLayout中,使用android:ori ...

  10. UIViewAnimationOptions类型

    一个非常强大的博客 http://www.cnblogs.com/kenshincui/    像我这种新手确实应该多看看   常规动画属性设置(可以同时选择多个进行设置) UIViewAnimati ...