在Loading界面加载assetBundle后在场景中加载Asset资源

Keywords:

    loading界面是我们做游戏的时候经常用的,loading界面里元素很少,只是用于过渡,在加载比较大的场景的时候使用,比如从A场景到C场景,因为C场景较大,先进入B场景,在B场景异步加载C场景,加载完成后进入C,这样做的好处就是告诉用户:游戏并没有卡死,耐心等待一会,通常loading界面都有一个进度条,读条完成后进入C场景。

    那么和AssetBundle有什么关系呢?因为loading在异步加载C场景之前,可以先进行AssetBundle加载,也就是先加载离线资源包然后加载场景。因为这两个过程都是异步加载,放在一起十分完美。类似下面这样:

    先简单介绍一下Loading场景的结构。loading比较简单,一般只绑定一条脚本,脚本中首先Start中加入携程函数,开启一个异步任务。

    void Start()
    {
        //在这里开启一个异步任务,进入loadScene方法。
        StartCoroutine(loadScene());
        
    }

    其中异步任务代码如下:

    IEnumerator loadScene()
    {
        //加上这么一句就可以先显示加载画面然后再进行加载  
        yield return new WaitForEndOfFrame();
        string path = "http://songshizhao.com/apps/AppData/rockhero/android/StreamingAssets/";
#if UNITY_ANDROID
        path = "http://songshizhao.com/apps/AppData/rockhero/android/StreamingAssets/";
#endif

#if UNITY_IPHONE
         path = "http://songshizhao.com/apps/AppData/rockhero/windows/StreamingAssets/";
#endif

#if UNITY_STANDALONE_WIN
         path = "http://songshizhao.com/apps/AppData/rockhero/windows/StreamingAssets/";
#endif

        path = path+ sceneLoad.BundleName[musicIndex]+ "."+ sceneLoad.BundleVarient[musicIndex];

        WWW www = WWW.LoadFromCacheOrDownload(path, 0);
    
        //等待下载完成
        yield return www;
        if (www.error != null)
        {
            //警告
            Debug.Log(www.error);
            yield break;
        }
        else
        {
            int musicindex = PlayerPrefs.GetInt("MusicIndex");
            //Debug.Log("打开的歌曲序号是"+ musicindex);
            //Debug.Log("打开的歌曲资源名字是" + sceneLoad.AssetName[musicIndex]);
            //Debug.Log("打开的歌曲显示名字是" + sceneLoad.songs[musicIndex]);
            //从bytes数组中创建AssetBundle
            AssetBundle assetBundle = www.assetBundle;

            AssetBundleRequest request = assetBundle.LoadAssetAsync(sceneLoad.AssetName[musicIndex], typeof(AudioClip));
            musics[musicIndex] = request.asset as AudioClip;
            AssetBundleRequest request2 = assetBundle.LoadAssetAsync(sceneLoad.AssetName[musicIndex], typeof(TextAsset));
            docs[musicIndex] = request2.asset as TextAsset;
            assetBundle.Unload(false);
        }

        async = SceneManager.LoadSceneAsync("myf");
        async.allowSceneActivation = false;//防止90%跳入场景 
    }

    上面的代码只有第一句和最后两句是异步加载场景的。unity异步加载场景有个小坑,也就是加载进度只有90的时候,就进入场景了,进度条到不了100%,所以最后一句控制一下,让进度条读到100的时候再切换界面。

    由于使用异步加载,在加载的时候界面上的元素还是可以更新的,在update中来做,用slider做进度条简直不要太简单,给sliderbar换一个外观,做一个sprite animation效果出来一点也不觉得勉强!良心推荐(如上图所示)。

    void Update()
    {
        if (async == null)
        {
            return;
        }
        if (async.progress < 0.9f)
        {
            toProgress = (int)(async.progress * 100);
        }
        else
        {
            toProgress = 100;
        }

        if (displayProgress < toProgress)
        {
            displayProgress++;
        }
        if (displayProgress == 100)//async.isDone应该是在场景被激活时才为true
        {
            async.allowSceneActivation = true;
        }
        loadingText.text = displayProgress+"%";
        progress_slider.value = displayProgress * 0.01f;       
    }

    上面图片是我自己做的音乐小游戏,美工能力很差,勿喷(⊙﹏⊙),将就看吧。对了上面还有一个核心问题没有说。B场景加载的asset内容怎么在C场景中使用呢?这个也简单。定义一个公共的静态变量就可以了。在C场景中使用B.asset就可以了。


 public static string[] BundleName = { "gx", "zmczx", "girlfriend", "numb", "sheismysin", 
"rollinginthedeep", "ghsy", "mhtc", "zdan", "wdzr" };


相关链接:unity使用网站webservice的简单办法

作者:songshizhao 发表于:2017-03-18T07:52:44 访问量:2852