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

本文主要是介绍Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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


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

 

Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一) - 雨松MOMO程序研究院 - 1

 

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

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

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

 

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

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


C#
1
Application.LoadLevelAsync("yourScene");

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

Application.LoadLevelAdditiveAsync("yourScene");

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

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

usingUnityEngine;
usingSystem.Collections;publicclassGlobe
{//在这里记录当前切换场景的名称
publicstaticstringloadName;
}


 

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

//记录LOADING场景中需要读取的C场景名称
Globe.loadName = "C";
//先进入B场景
Application.LoadLevel ("B");
OK我们在B场景中异步读取C场景与 播放读取动画,Loading.cs 绑定在B场景的摄像机对象身上。当C场景异步读取完毕后即可直接进入C场景。

using UnityEngine;
using System.Collections;public class Loading : MonoBehaviour {private float fps = 10.0f;private float time;//一组动画的贴图,在编辑器中赋值。public Texture2D[] animations;private int nowFram;//异步对象AsyncOperation async;//读取场景的进度,它的取值范围在0 - 1 之间。int progress = 0;void Start(){//在这里开启一个异步任务,//进入loadScene方法。StartCoroutine(loadScene());}//注意这里返回值一定是 IEnumeratorIEnumerator loadScene(){//异步读取场景。//Globe.loadName 就是A场景中需要读取的C场景名称。async = Application.LoadLevelAsync(Globe.loadName);//读取完毕后返回, 系统会自动进入C场景yield return async;}void OnGUI(){//因为在异步读取场景,//所以这里我们可以刷新UIDrawAnimation(animations);}void Update(){//在这里计算读取的进度,//progress 的取值范围在0.1 - 1之间, 但是它不会等于1//也就是说progress可能是0.9的时候就直接进入新场景了//所以在写进度条的时候需要注意一下。//为了计算百分比 所以直接乘以100即可progress =  (int)(async.progress *100);//有了读取进度的数值,大家可以自行制作进度条啦。Debug.Log("xuanyusong" +progress);}//这是一个简单绘制2D动画的方法,没什么好说的。void   DrawAnimation(Texture2D[] tex){time += Time.deltaTime;if(time >= 1.0 / fps){nowFram++;time = 0;if(nowFram >= tex.Length){nowFram = 0;}}GUI.DrawTexture(new Rect( 100,100,40,60) ,tex[nowFram] );//在这里显示读取的进度。GUI.Label(new Rect( 100,180,300,60), "lOADING!!!!!" + progress);}}

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



 

Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一) - 雨松MOMO程序研究院 - 2


 

Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一) - 雨松MOMO程序研究院 - 2


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

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

using UnityEngine;
using System.Collections;public class Test : MonoBehaviour {//这里是需要加载激活的游戏对象public GameObject  [] Objects;//当前加载的进度int load_index =0;void Start (){//开启一个异步任务,加载模型。StartCoroutine(loadObject());}IEnumerator loadObject(){//便利所有游戏对象foreach(GameObject obj in Objects){//激活游戏对象obj.active = true;//记录当前加载的对象load_index ++;//这里可以理解为通知主线程刷新UIyield return 0;}//全部便利完毕返回yield return 0;}void OnGUI (){//显示加载的进度GUILayout.Box("当前加载的对象ID是: " + load_index);}
}

 



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

 

Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一) - 雨松MOMO程序研究院 - 3

 

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

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


 

using UnityEngine;
using System.Collections;public class Main : MonoBehaviour{public int count;//在编辑器中预设一个游戏对象public  GameObject prefab;void Start (){StartCoroutine(loaditem());}void OnGUI(){GUILayout.Box("游戏对象已经加载到 : " + count);}IEnumerator loaditem(){//开始加载游戏对象for(int i =0; i< 1000; i++){Instantiate(prefab);count = i;//可以理解为刷新UI,显示新加载的游戏对象yield return 0;}//结束yield return 0;}
}



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






 


这篇关于Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/820882

相关文章

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

Java 枚举的基本使用方法及实际使用场景

《Java枚举的基本使用方法及实际使用场景》枚举是Java中一种特殊的类,用于定义一组固定的常量,枚举类型提供了更好的类型安全性和可读性,适用于需要定义一组有限且固定的值的场景,本文给大家介绍Jav... 目录一、什么是枚举?二、枚举的基本使用方法定义枚举三、实际使用场景代替常量状态机四、更多用法1.实现接

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示

使用Python获取JS加载的数据的多种实现方法

《使用Python获取JS加载的数据的多种实现方法》在当今的互联网时代,网页数据的动态加载已经成为一种常见的技术手段,许多现代网站通过JavaScript(JS)动态加载内容,这使得传统的静态网页爬取... 目录引言一、动态 网页与js加载数据的原理二、python爬取JS加载数据的方法(一)分析网络请求1

Java集成Onlyoffice的示例代码及场景分析

《Java集成Onlyoffice的示例代码及场景分析》:本文主要介绍Java集成Onlyoffice的示例代码及场景分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 需求场景:实现文档的在线编辑,团队协作总结:两个接口 + 前端页面 + 配置项接口1:一个接口,将o