用过MOMO那个方法的都应该会发现了,当进度条开始显示的时候,基本上已经加载到80%了,可能也跟Unity版本有关,我的是4.3.4 。但是实际上Unity的工作原理差不多就那样,在Start里面直接开始加载的协程,实际上一开始就会阻塞,导致画面刚刚渲染出来的时候,已经完成了一部分的加载,而很多资源会在一开始就加载了,如果这里的资源太多了,那么就会像我一样,显示很长时间的白屏,肯定加载画面出来的时候,进度已到80%,而且剩余的20%花费时间很短,一闪就过去了。
那么要怎么解决这个问题呢,其实做过同步加载的人都知道,要选渲染加载画面再加载,Unity自称异步加载,实际上还是同步,了解协程的都知道,那个东西和线程半毛钱关系没有,依然是个同步方法。不知道Unity何时才能提供真正的多线程加载支持,这种加载方式感觉越来越不入流了。
不喜欢看废话的,直接跳过上面看修改后的代码
实际上就是只加上一句yield return new WaitForEndOfFrame();
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()); } //注意这里返回值一定是 IEnumerator IEnumerator loadScene() { yield return new WaitForEndOfFrame();//<strong>加上这么一句就可以先显示加载画面然后再进行加载</strong> async = Application.LoadLevelAsync(Globe.loadName); //读取完毕后返回, 系统会自动进入C场景 yield return async; } void OnGUI() { //因为在异步读取场景, //所以这里我们可以刷新UI DrawAnimation(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); } }
实际上即使这样的加载也是非常有问题的,那就是资源会集中在一起加载,也就是刚开始加载到百分之几,然后卡住相当长的时间,然后突然到80%左右。解决这个问题估计只能用把资源都分包的方法了,这个还在研究中。
不过有趣的是,如果直接使用Unity自带的资源包,第一次虽然会慢点,但是只要加载过一次,即使你关闭了游戏,再次打开就基本上无需加载,虽然这样就失去了加密的保护。但现在下结论为时过早,说不定即使加密分包,也可以做到这样,虽然不知道这个是什么机制,但是我感觉还是不太可能。
引用:http://www.xuanyusong.com/archives/1427