`

unity深入研究--之异步加载游戏场景与异步加载游戏资源进度条

 
阅读更多
异步任务相信大家应该不会陌生,那么本章内容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 publicstatic stringloadName;
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 privatefloat fps = 10.0f;
07 privatefloat time;
08 //一组动画的贴图,在编辑器中赋值。
09 publicTexture2D[] animations;
10 privateint nowFram;
11 //异步对象
12 AsyncOperation async;
13
14 //读取场景的进度,它的取值范围在0 - 1 之间。
15 intprogress = 0;
16
17 voidStart()
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 yieldreturn async;
33
34 }
35
36 voidOnGUI()
37 {
38 //因为在异步读取场景,
39 //所以这里我们可以刷新UI
40 DrawAnimation(animations);
41
42 }
43
44 voidUpdate()
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 voidDrawAnimation(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(newRect( 100,100,40,60) ,tex[nowFram] );
76
77 //在这里显示读取的进度。
78 GUI.Label(newRect( 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 publicGameObject [] Objects;
08
09 //当前加载的进度
10 intload_index =0;
11 voidStart ()
12 {
13 //开启一个异步任务,加载模型。
14 StartCoroutine(loadObject());
15 }
16
17 IEnumerator loadObject()
18 {
19 //便利所有游戏对象
20 foreach(GameObject objin Objects)
21 {
22 //激活游戏对象
23 obj.active =true;
24 //记录当前加载的对象
25 load_index ++;
26
27 //这里可以理解为通知主线程刷新UI
28 yieldreturn 0;
29 }
30 //全部便利完毕返回
31 yieldreturn 0;
32 }
33
34 voidOnGUI ()
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 publicint count;
08 //在编辑器中预设一个游戏对象
09 publicGameObject prefab;
10
11 voidStart ()
12 {
13 StartCoroutine(loaditem());
14 }
15
16 voidOnGUI()
17 {
18 GUILayout.Box("游戏对象已经加载到 : "+ count);
19 }
20
21 IEnumerator loaditem()
22 {
23 //开始加载游戏对象
24 for(inti =0; i< 1000; i++)
25 {
26
27 Instantiate(prefab);
28 count = i;
29 //可以理解为刷新UI,显示新加载的游戏对象
30 yieldreturn 0;
31 }
32 //结束
33 yieldreturn 0;
34 }
35 }

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

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

分享到:
评论

相关推荐

    unity实现场景异步加载并带有加载的进度条

    unity实现场景异步加载并带有加载的进度条,实现场景平稳加载,返回的加载进度为匀速加载。非常适合用在要加载大型场景的情况下。

    Unity3D游戏开发之异步加载游戏场景与异步加载游戏资源进度条.docx

    Unity3D提供了两种异步加载场景的方法: - `Application.LoadLevelAsync("yourScene")`:这是完全异步加载场景的方式,会替换当前场景,适合于游戏的关卡切换。加载过程中,玩家可以继续在当前场景活动,直到新...

    Unity3D游戏开发之异步加载游戏场景与异步加载游戏资源进度条.pdf

    Unity提供了两种异步加载场景的方法: 1. `Application.LoadLevelAsync("yourScene")`:这个方法会异步加载新场景,并在加载完成后自动替换当前场景。加载过程中,旧场景的游戏对象会被销毁,新场景成为主场景。...

    Unity3D之异步加载游戏场景中关于进度条显示

    Unity3D之异步加载游戏场景中关于进度条显示

    Unity3D多个异步加载场景资源 简洁漂亮的加载画面

    在Unity3D游戏开发中,异步加载(Asynchronous Loading)是提高用户体验的关键技术之一,尤其是在处理大型场景或大量资源时。本项目提供了一个简洁且漂亮的加载画面,旨在帮助Unity3D学者理解和实现游戏资源的高效...

    Unity3D之异步加载与进度条

    Unity3D之异步加载与进度条 Unity3D 中的异步加载是一种高效的加载方式,能够减少加载时间,提高游戏体验。下面我们将详细介绍 Unity3D 中的异步加载与进度条的实现。 异步加载 异步加载是一种非阻塞式的加载...

    unity addressables 加载资源和场景 显示进度条(主要用于WebGL)

    Unity Addressables 是Unity引擎提供的一种资源管理框架,用于动态加载和卸载游戏中的资源和场景,从而优化内存使用和提高游戏性能。相比传统的Resources加载方式,Addressables支持异步加载,能够实现更高效的资源...

    unity场景异步加载进度条小场景

    "unity场景异步加载进度条小场景"是一个专为场景切换设计的资源包,它包含了精美的背景和炫彩的进度条,以提供一个直观的加载界面,使用户在等待场景加载时能有一个良好的视觉体验。 首先,我们要理解Unity中的场景...

    Unity3D异步加载场景代码

    ### Unity3D异步加载场景代码详解 #### 引言 在Unity3D游戏开发过程中,为了提升用户体验、减少加载时间以及避免游戏卡顿等问题,异步加载技术被广泛采用。通过异步加载,可以在后台预加载场景资源,使得用户在...

    异步加载进度条案例素材.zip

    在Unity游戏开发中,异步加载(Async Operations)是一项关键技术,它允许我们在不阻塞主游戏流程的情况下加载资源,如场景、纹理、音频等。进度条是展示这种加载过程直观方式,为用户提供加载状态的反馈,提升用户...

    Unity异步加载场景

    避免了跳转场景时界面卡住不动的尴尬,使用时只需把scene0放入游戏的第一个场景即可,跳转场景时直接调用ChangeSceneManager.Instance.ChangeScene()方法即可进入动态加载场景界面,无需再创建跳转场景的UI。...

    dotnet-UnityImageLoader用于Unity中的图片异步显示加载库

    Unity-ImageLoader是一款专为Unity游戏引擎设计的图片异步加载库,主要目的是优化游戏性能,提高用户体验。在Unity中,直接加载大图或者大量的图片可能会导致应用卡顿,因此异步加载技术变得尤为重要。这款库是基于...

    Unity3D动态加载进度条

    在Unity3D游戏开发中,动态加载进度条是提高用户体验的关键元素之一,尤其是在处理大型场景或需要异步加载资源时。本教程将详细介绍如何在Unity3D中实现一个简单而实用的场景加载进度条,同时展示百分比进度,以提供...

    unity通过协程实现异步下载数据并加载

    在游戏开发中,数据的异步下载和加载是至关重要的,特别是对于大型游戏,因为它们通常需要大量的资源,如纹理、音频、模型和场景数据。为了不阻塞游戏主循环,Unity3D引入了协程(Coroutine)的概念,允许开发者以非...

    Unity3D 场景加载过渡资源 异步加载场景资源 附带自然的加载画面 公司项目demo 亲测好用 pc和安卓都支持

    "异步加载场景动画demo"可能包含了实现上述功能的源代码和场景文件,这为开发者提供了一个可以直接学习和参考的实例。通过分析和调试这些代码,开发者可以深入理解Unity3D中的异步加载和过渡动画的实现细节。 总结...

    Unity可自定义loading页的异步加载工具,免费下载,使用说明

    总的来说,这个工具为Unity开发者提供了一个便捷的方式来实现异步加载场景并自定义加载界面,从而提高游戏的加载体验。通过深入学习和应用这些知识点,开发者可以打造出更加流畅、用户体验更佳的游戏产品。在使用前...

    U3D加载进度条

    对于大型游戏或包含大量资源的场景,通常选择异步加载,并配合进度条展示加载进度。 实现加载进度条涉及以下几个关键步骤: 1. **创建进度条UI**:首先,在Unity的Canvas上创建一个UI Slider组件,用于显示加载...

    Unity 3D开发-SceneManager场景管理(异步使用同一个过渡场景)

    在U3D开发过程中经常使用到多场景的切换,有同步SceneManager.LoadScene()和异步SceneManager.LoadSceneAsync()两种方法,同步的话一般就会卡住界面直到加载完成,使用异步的话一般都做一个加载的进度条,每次切换的...

    Unity3D之进度条插件Loading Component

    3. **配置加载场景**:在Unity编辑器中创建一个新的Canvas,并添加Loading Component脚本到一个UI GameObject上。然后根据需求设置相关的参数,如背景图片、进度条样式等。 #### 三、主要功能特点 1. **高度可定制...

    游戏加载进度条2

    在Unity游戏开发中,加载进度条是一个非常常见的需求,它能提供给玩家一个可视化的反馈,展示游戏资源或数据加载的进度。这个【标题】"游戏加载进度条2" 和【描述】暗示了我们正在讨论如何在Unity中实现这样一个功能...

Global site tag (gtag.js) - Google Analytics