Unity3D-UGUI-Image制作异步加载场景进度条
2017-11-07 17:50
471 查看
先看一下我的成果
问题
我们通常在玩游戏的时候,会看到进度条加载,为什么要这样做那?
仔细分析一下我们就会明白,其实是主场景包含的资源较多,直接导致加载场景的时间较长,影响了玩家的体验。对于这样的情况,是很容易引起玩家反感的,为了避免这种情形的发生,添加一个加载Loading场景,然后再通过Loading场景来加载主场景,是势在必行的。因为Loading场景包含的资源较少,所以加载速度快。在加载主场景的时候一般会在Loading界面中显示一个进度条来告知玩家当前加载的进度。在Unity中可以通过调用Application.LoadLevelAsync函数来异步加载游戏场景,通过查询AsyncOperation.progress的值来得到场景加载的进度。//单击加载按钮 public void LoadButton() { //通过协同加载程序 StartCoroutine(StartLoading(1)); } //定义协同 private IEnumerator StartLoading(int scene) { //异步加载场景 AsyncOperation op = Application.LoadLevelAsync(scene); //是否操作完成 while(!op.isDone) { SetLoadingPercentage(op.progress * 100); yield return new WaitForEndOfFrame(); } } //设置显示进度 private void SetLoadingPercentage(int DisplayProgress) { progressImg.fillAmount = DisplayProgress * 0.01f; proText.text = DisplayProgress.ToString() + "%"; }
到这里是不是就已经可以实现了那,我只能说基本功能都实现,但是效果不会是理想的。
因为,上面的代码的结果是,进度条并没有连续的显示加载的进度,数字也不是连续出现的,在没有显示到100%就情况下,就直接切换场景了。为什么会是这样那?通过查找资料原因,我们可以发现,其原因在于Application.LoadLevelAsync并不是真正的后台加载,它在每一帧加载一些游戏资源,并给出一个progress值,所以在加载的时候还是会造成游戏卡顿,AsyncOperation.progress的值也不够精确。当场景加载完毕后就直接自动切换场景了,上述代码中的while循环体内的代码是不会被调用的,这就直接导致进度条不会显示100%。那么怎么来解决这个问题那?
其实这个问题可以用Unity提供的手动切换场景的方法来解决,把AsyncOperation.allowSceneActivation设为false就可以禁止Unity加载完毕后自动切换场景,修改后的代码如下:private IEnumerator StartLoading(int scene) { AsyncOperation op = Application.LoadLevelAsync(scene); op.allowSceneActivation = false; while(!op.isDone) { SetLoadingPercentage(op.progress * 100); yield return new WaitForEndOfFrame(); } op.allowSceneActivation = true; }
到这里是不是就可以实现想要的结果了。
遗憾的是,执行的结果是进度条最后会一直停留在90%上,场景不会切换。通过打印log发现AsyncOperation.isDone一直为false,AsyncOperation.progress的值增加到0.9后就保持不变了,也就是说场景永远不会被加载完毕。为了解决这个问题,可以当AsyncOperation.progress到达0.9后,就直接把进度条的数值改为为100%,然后设置AsyncOperation.allowSceneActivationAsyncOperation.allowSceneActivation为ture,让Unity继续加载未完成的场景。修改后的代码如下:private IEnumerator StartLoading(int scene) { AsyncOperation op = Application.LoadLevelAsync(scene); op.allowSceneActivation = false; while(op.progress < 0.9f) { SetLoadingPercentage(op.progress * 100); yield return new WaitForEndOfFrame(); } SetLoadingPercentage(100); yield return new WaitForEndOfFrame(); op.allowSceneActivation = true; }
运行上面的代码,我们就会发现,虽然我们解决了进度条到达不了100%的问题,但是进度条进度的显示数字并不连续,和自己理想的状态还是有些不一致,所以看上去不够自然和美观。
为了看上去像是在连续加载,可以每一次更新进度条的时候插入过渡数值。这里我采用的策略是当获得AsyncOperation.progress的值后,不立即更新进度条的数值,而是每一帧在原有的数值上加1,这样就会产生数字连续的动画效果了。private IEnumerator StartLoading(int scene) { int displayProgress = 0; int toProgress = 0; AsyncOperation op = Application.LoadLevelAsync(scene); op.allowSceneActivation = false; while(op.progress < 0.9f) { toProgress = (int)op.progress * 100; while(displayProgress < toProgress) { ++displayProgress; 4000 SetLoadingPercentage(displayProgress); yield return new WaitForEndOfFrame(); } } toProgress = 100; while(displayProgress < toProgress){ ++displayProgress; SetLoadingPercentage(displayProgress); yield return new WaitForEndOfFrame(); } op.allowSceneActivation = true; }
写到这里,终于可以实现一个进度条的加载了,下面是我做进度条的步骤和代码,希望能给你们一些参考。挂在脚本实现操作如图所示:
image组件progress,image Type:Filled , Fill Method : Horizontal
代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class LoginManage : MonoBehaviour { public static LoginManage instance; //加载界面 public GameObject loadPanel; //滑动进度条 public Image progressImg; //进度显示百分比 public Text proText; // Use this for initialization void Start () { instance = this; loadPanel.SetActive(false);//一开始禁用加载层。 } // Update is called once per frame void Update () { if(Input.GetKeyDown(KeyCode.Escape)) { ExitGamePressed(); } } /// <summary> /// 登录按钮点击事件 /// </summary> public void NewGamePressed() { StartCoroutine(StartLoading("Main"));//调用加载场景的协程 loadPanel.SetActive(true);//启用加载界面 } /// <summary> /// EXIT按钮点击事件 /// </summary> /// <returns></returns> public void ExitGamePressed() { //退出整个游戏 Application.Quit(); } private void SetLoadingPercentage(int DisplayProgress) //设置显示进度 { progressImg.fillAmount = DisplayProgress * 0.01f; proText.text = DisplayProgress.ToString() + "%"; } /// <summary> /// 加载场景协程 /// </summary> private IEnumerator StartLoading(string sceneName) { int displayProgress = 0; int toProgress = 0; AsyncOperation op = SceneManager.LoadSceneAsync(sceneName); //异步对象 op.allowSceneActivation = false; while (op.progress < 0.9f) { toProgress = (int)op.progress * 100; while (displayProgress < toProgress) { ++displayProgress; SetLoadingPercentage(displayProgress); yield return new WaitForEndOfFrame(); } } toProgress = 100; while (displayProgress < toProgress) { ++displayProgress; SetLoadingPercentage(displayProgress); yield return new WaitForEndOfFrame(); } op.allowSceneActivation = true; } }
相关文章推荐
- Unity3D之UGUI——制作异步加载场景进度条
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
- Unity3D 场景切换异步加载进度
- (转)Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
- Unity3D学习之异步加载游戏场景与异步加载游戏资源进度条
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度
- [Unity3D]异步加载游戏场景与异步加载游戏资源进度条
- [Unity3D]异步加载游戏场景与异步加载游戏资源进度条
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
- (转)Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条(三十一)
- Unity3d_UGUI加载场景进度条
- UGUI提高<四> 异步加载场景进度条
- unity3d异步加载场景
- Unity3D 使用 WWW 加载场景并显示进度条
- 【Unity】场景异步加载进度条的制作
- Unity3D——异步加载游戏场景loading界面的开发
- Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条
- Unity3D异步加载游戏场景
- Unity3d场景加载进度条