Unity客户端断点续传

来源:互联网 发布:mac安装win10不保留ox 编辑:程序博客网 时间:2024/06/06 01:53

转自:http://www.jianshu.com/p/5c40f60b55dd

Unity版本: 5.3

使用语言: C#


写在前面

版本的更新和迭代经常遇见,Unity中我们可以使用AssetBundle进行资源更新,这个非常方便,客户端方面下载资源到本地,肯定是要使用断点续传的。

实现功能:

   1.使用AssetBunlde压缩场景上传到服务器   2.使用C# Net库实现下载方法(断点续传)   3.使用Unity的WWW加载使用资源

1.使用AssetBunlde压缩场景上传到服务器

Unity5.X使用AssetBundle打包场景,可以在可视化视图将要压缩的资源添加AssetBundle标签,执行Build。

为了方便测试,我将打包好的资源上次到云盘,然后共享了下载链接,供我测试,注意百度云人家也不是傻子,下载链接隔天会失效。

using UnityEngine;using System.Collections;using UnityEditor;public class AssetBundleCreate : MonoBehaviour {    [MenuItem("MS/AssetBundleCreate")]    public static void Build()    {        //将资源打包到StreamingAssets文件夹下        BuildPipeline.BuildAssetBundles(Application.streamingAssetsPath);    }}

2.使用C#Net库实现下载方法(断点续传)

大家记住,计算机追求的是效率,关于费时的操作我们一定要用异步方法或者子线程去处理。

下载资源,肯定是用子线程去处理的,System.Net库里面有HttpWebRequset类,提供了访问网址的工具类,我们可以用它下载资源,下载过程中涉及文件处理的操作,这里用到了流的概念,不懂的先去学习流。

using UnityEngine;using System.Collections;using System.Threading;using System.IO;using System.Net;using System;/// <summary>/// 通过http下载资源/// </summary>public class HttpDownLoad {    //下载进度    public float progress{get; private set;}    //涉及子线程要注意,Unity关闭的时候子线程不会关闭,所以要有一个标识    private bool isStop;    //子线程负责下载,否则会阻塞主线程,Unity界面会卡主    private Thread thread;    //表示下载是否完成    public bool isDone{get; private set;}    /// <summary>    /// 下载方法(断点续传)    /// </summary>    /// <param name="url">URL下载地址</param>    /// <param name="savePath">Save path保存路径</param>    /// <param name="callBack">Call back回调函数</param>    public void DownLoad(string url, string savePath, Action callBack)    {        isStop = false;        //开启子线程下载,使用匿名方法        thread = new Thread(delegate() {            //判断保存路径是否存在            if(!Directory.Exists(savePath))            {                Directory.CreateDirectory(savePath);            }            //这是要下载的文件名,比如从服务器下载a.zip到D盘,保存的文件名是test            string filePath = savePath + "/test";            //使用流操作文件            FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);            //获取文件现在的长度            long fileLength = fs.Length;            //获取下载文件的总长度            long totalLength = GetLength(url);            //如果没下载完            if(fileLength < totalLength)            {                //断点续传核心,设置本地文件流的起始位置                fs.Seek(fileLength, SeekOrigin.Begin);                HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;                //断点续传核心,设置远程访问文件流的起始位置                request.AddRange((int)fileLength);                Stream  stream = request.GetResponse().GetResponseStream();                byte[] buffer = new byte[1024];                //使用流读取内容到buffer中                //注意方法返回值代表读取的实际长度,并不是buffer有多大,stream就会读进去多少                int length = stream.Read(buffer, 0, buffer.Length);                while(length > 0)                {                    //如果Unity客户端关闭,停止下载                    if(isStop) break;                    //将内容再写入本地文件中                    fs.Write(buffer, 0, length);                    //计算进度                    fileLength += length;                    progress = (float)fileLength / (float)totalLength;                    UnityEngine.Debug.Log(progress);                    //类似尾递归                    length = stream.Read(buffer, 0, buffer.Length);                }                stream.Close();                stream.Dispose();            }            else            {                progress = 1;            }            fs.Close();            fs.Dispose();            //如果下载完毕,执行回调            if(progress == 1)            {                isDone = true;                if(callBack != null) callBack();            }        });        //开启子线程        thread.IsBackground = true;        thread.Start();    }    /// <summary>    /// 获取下载文件的大小    /// </summary>    /// <returns>The length.</returns>    /// <param name="url">URL.</param>    long GetLength(string url)    {        HttpWebRequest requet = HttpWebRequest.Create(url) as HttpWebRequest;        requet.Method = "HEAD";        HttpWebResponse response = requet.GetResponse() as HttpWebResponse;        return response.ContentLength;    }    public void Close()    {        isStop = true;    }}

3.使用Unity的WWW加载使用资源

注意,测试的时候下载地址URL,你需要时时更新。

using UnityEngine;using System.Collections;using UnityEngine.SceneManagement;using UnityEngine.UI;using System;using System.Net;using System.IO;public class Test : MonoBehaviour {    bool isDone;    Slider slider;    Text text;    float progress = 0f;    void Awake()    {        slider = GameObject.Find("Slider").GetComponent<Slider>();        text = GameObject.Find("Text").GetComponent<Text>();    }    HttpDownLoad http;    //隔天之后你需要更新    string url = @"http://nj02all01.baidupcs.com/file/430d880872a1df2c585fdc5d2e1792f7?bkt=p3-00002196e1874bd1f274c739d3812e1223d6&fid=790124421-250528-1052161399548620&time=1453345864&sign=FDTAXGERLBH-DCb740ccc5511e5e8fedcff06b081203-EfEvaTITEN88hc7NwREKd3I5MXs%3D&to=nj2hb&fm=Nan,B,G,ny&sta_dx=14&sta_cs=0&sta_ft=test&sta_ct=0&fm2=Nanjing02,B,G,ny&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=00002196e1874bd1f274c739d3812e1223d6&sl=76480590&expires=8h&rt=sh&r=476311478&mlogid=474664903050570371&vuk=790124421&vbdid=3229687100&fin=test&slt=pm&uta=0&rtype=1&iv=0&isw=0&dp-logid=474664903050570371&dp-callid=0.1.1";    string savePath;    void Start () {        savePath = Application.streamingAssetsPath;        http = new HttpDownLoad();        http.DownLoad(url, savePath, LoadLevel);    }    void OnDisable()    {        print ("OnDisable");        http.Close();    }    void LoadLevel()    {        isDone = true;    }    void Update()    {        slider.value = http.progress;        text.text = "资源加载中" + (slider.value * 100).ToString("0.00") + "%";         if(isDone)        {            isDone = false;            string url = @"file://" + Application.streamingAssetsPath + "/test";            StartCoroutine(LoadScene(url));        }    }    IEnumerator LoadScene(string url)    {        WWW www = new WWW(url);        yield return www;        AssetBundle ab = www.assetBundle;        SceneManager.LoadScene("Demo2_towers");    }}

工程下载地址
密码:8c36

写在最后

 我们一般会采用多线程下载,这样速度更快,但是基础还是要学的。 #成功的道路没有捷径,代码这条路更是如此,唯有敲才是王道。
0 0
原创粉丝点击