下用Loading之异步加载游戏场景与异步游戏资源的制作

下用Loading之异步加载游戏场景与异步游戏资源的制作

上一篇介绍了游戏开始场景的制作unity 异步加载场景,但是目前还没有交互。 按理说我的设计是点击界面然后直接进入游戏场景,但是看到宇松的这篇文章--Unity3D研究院异步加载游戏场景和异步加载游戏资源进度条后,我决定尝试使用Loading接口异步加载游戏。

先看我的Loading界面:

unity 异步加载场景_unity 动态加载场景_unity异步加载场景优化

像我这样的小demo,从开始场景到游戏场景都可以使用Application.LoadLevel,但是对于普通游戏来说,新场景的资源加载往往会让你的游戏卡一会,用户体验很差就像游戏死了一样。 这时候Loading接口和后台异步加载场景就是一个很好的解决方案。 看看我是怎么做的。

1. 一、Loading场景的制作

这个比较简单。 如上图所示,只是使用了NGUI的Texture。 需要注意的是给它添加一个Stretch,让屏幕分辨率自适应。 我不知道该怎么做。 见我之前的文章。 这里就不介绍NGUI是怎么工作的了。 完毕。

2.异步加载游戏场景

Application.LoadLevel("SceneName") 最简单的方法就是同步加载场景。 如果使用这种方式,新场景的资源小,但是如果资源大,你的游戏在加载资源的时候会卡顿。 直到新场景的资源全部加载完毕,这种方式显然不利于用户体验。 最传统的方法是开一个线程,一个线程用来处理数据加载,一个线程用进度条或者动画提示玩家游戏不是卡死,而是等待。 但是Unity3d没有多线程的概念,但是unity也为我们提供了后台加载场景的StartCoroutine(协同程序)和LoadLevelAsync(异步加载关卡)方法。

为什么 StartCoroutine 被称为协作程序? 所谓协同,就是当你在StartCoroutine的函数体中处理一段代码时,使用yield语句等待执行结果。 在此期间unity 异步加载场景,不影响主程序的继续执行,可以协同工作。 而LoadLevelAsync允许你在后台加载新的资源和场景,所以通过协同,你可以在前台使用加载条或者动画来提醒玩家游戏没有卡顿3D道具,同时后台坐标来处理加载事项。 如果你想了解更多关于StartCoroutine的信息,可以看这里:MonoBehaviour.StartCoroutine启动协作程序。 如果您想了解有关 LoadLevelAsync 的更多信息,可以在此处查看:Application.LoadLevelAsync 异步加载关卡。

3.使用单例类记录场景名称

singleton脚本和singleton类在我之前的文章中已经介绍过,这里就不多说了,为什么要用singleton类,因为Loading脚本需要知道接下来要加载什么场景,而这就是之前的场景告诉 是的,场景切换数据会丢失,单例类的数据会永远保留3D素材,所以应该使用单例类。 看一下代码:

public class Global {
	public string loadName;
	
	private static Global instance;
	public static Global GetInstance()
	{
		if (instance == null)
			instance = new Global();
		
		return instance;
	}
}

这里有一个变量loadName,负责记录场景的名称。

4.从A场景过渡到Loading场景

我之前的文章讲过开始游戏场景的制作,但是缺少切换场景的过渡。 如果是场景,我用触屏的方式让它过渡到Loading场景,然后通过协同程序等待资源自动加载。 过渡到B场景。 先看场景A的代码:

public class OnPress : MonoBehaviour {
	// Use this for initialization
	public UICamera nguiCamera;
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		if (Input.GetMouseButton(0)) {
			Ray ray = nguiCamera.camera.ScreenPointToRay(Input.mousePosition);
			RaycastHit hit;
			if (Physics.Raycast(ray, out hit)) {
				Global.GetInstance().loadName = "GameScene";
				Application.LoadLevel("LoadingScene");
			}
		}
	}
}

touch代码我就不解释了,重要的是两句,“Global.GetInstance().loadName = "GameScene";",告诉Loading场景下一个要加载的场景是GameScene,然后"Application .LoadLevel ("LoadingScene");" 开始将场景切换到 LoadingScene。

5. LoadingScene 协作程序在后台加载新场景。

先看代码:

public class Loading : MonoBehaviour {
	void Start () {
		StartCoroutine(loadScene());
	}
	
	IEnumerator loadScene()
	{
		AsyncOperation async = Application.LoadLevelAsync(Global.GetInstance().loadName);
		yield return async;
	}
}

这是最简单的协作程序。 它只是在后台处理和加载新场景。 没有前台工作。 本文不谈前台工作。 代码很简单,就不解释了。 因为Global.GetInstance().loadName = "GameScene",加载后会自动跳转到GameScene场景。

6.切换场景,有一个必须的工作没有做。 也就是在Unity中注册场景。

选择File->Build Settings...,上面有一个Scenes In Build,需要把你用到的所有场景都添加到这个框里,程序才能正常调用,否则程序无效。 右下角有一个Add Current按钮,用于加载当前场景,也可以直接将所有场景拖到这里。 后面的数字是关卡 ID,0 是第一个加载的场景。 我的截图如下:

unity 动态加载场景_unity 异步加载场景_unity异步加载场景优化

这样在协同异步加载的场景中就可以实现最简单的Loading场景,但是这篇文章中的协同异步加载场景其实是没有意义的,因为我们前台什么都不做。 在接下来的文章中,让我们的前台也没有闲着。 顺便看看U3D是如何工作的。 使用 XML 加载游戏提示。