zoukankan      html  css  js  c++  java
  • [原]unity3d之http多线程异步资源下载

    郑重声明:转载请注明出处 U_探索

    本文诞生于乐元素面试过程,被面试官问到AssetBundle多线程异步下载时,愣了半天,同样也被深深的鄙视一回(做了3年多u3d 这个都没用过),所以发誓要实现出来填补一下自己的空白,同时分享给大家。说明:本人只在pc和Android下测试好使,其他平台未知!

    直接贴代码,都是C# http的API,不懂得自己百科。

    using UnityEngine;
    using System.Collections;
    using System;
    using System.Text;
    using System.Net;
    using System.IO;
    
    
    internal class WebReqState
    {
        public byte[] Buffer;
        
        public FileStream fs;
        
        public const int BufferSize = 1024;
        
        public Stream OrginalStream;
        
        public HttpWebResponse WebResponse;
        
        public WebReqState(string path)
        {
            Buffer = new byte[1024];
            fs = new FileStream(path,FileMode.Create);
        }
    
    }
    
    public class HttpHelper {
    
        string path = null;
        string assetName;
        public HttpHelper(string path)
        {
            this.path = path;
        }
        
        public  void AsyDownLoad(string url)
    {
        Debug.Log(url);
        assetName = url.Split('/')[4];
        Debug.Log(assetName);
        HttpWebRequest httpRequest = WebRequest.Create(url) as HttpWebRequest;
        httpRequest.BeginGetResponse( new AsyncCallback(ResponseCallback), httpRequest);
    }
        
        void ResponseCallback(IAsyncResult ar)
    {
        HttpWebRequest req = ar.AsyncState as HttpWebRequest;
        if(req == null) return;
        HttpWebResponse response = req.EndGetResponse(ar) as HttpWebResponse;
        if(response.StatusCode != HttpStatusCode.OK)
        {
            response.Close();
            return;
        }
        Debug.Log(path+ "/"+assetName);
        WebReqState st = new WebReqState(path+ "/"+assetName);
        st.WebResponse = response;
        Stream responseStream = response.GetResponseStream();
        st.OrginalStream = responseStream;
        responseStream.BeginRead(st.Buffer,0,WebReqState.BufferSize,new AsyncCallback(ReadDataCallback),st);
    }
        
        void ReadDataCallback(IAsyncResult ar)
    {
        WebReqState rs = ar.AsyncState as WebReqState;
        int read =rs.OrginalStream.EndRead(ar);
        if(read>0)
        {
            rs.fs.Write(rs.Buffer,0,read);
            rs.fs.Flush();
            rs.OrginalStream.BeginRead(rs.Buffer, 0, WebReqState.BufferSize, new AsyncCallback(ReadDataCallback), rs);
        }
        else
        {
            rs.fs.Close();
            rs.OrginalStream.Close();
            rs.WebResponse.Close();
            Debug.Log(assetName+":::: success");
        }
    }
    }
    View Code

    下载部分:

    if(GUI.Button(new Rect(0,0,100,30),"test"))
    {
        string rootPath = Application.persistentDataPath;//android上保存到 /storage/sdcard0/Android/data/包名(例如:com.example.test)/files
        for(int i =0;i<str.Length;i++) //str是string型数组,存放部分assetbundle名字
        {
            Thread thread = new Thread(new ParameterizedThreadStart(DownAsset)); //ParameterizedThreadStart 多线程传参 
            thread.Start(rootPath+"|"+str[i]); //只能带一个object参数 所以使用字符串拼接
        }
    } 
        
    void DownAsset(System.Object file)
    {
        string[] fileName = file.ToString().Split('|');
        HttpHelper help = new HttpHelper(fileName[0]);
        help.AsyDownLoad("http://192.168.0.103/unity/"+fileName[1]+".AssetBundle");//注意在手机上测试 该对Ip地址
    }

    下载完成后 可以去/storage/sdcard0/Android/data/包名(例如:com.example.test)/files查找对应文件

    加载部分:

    if(GUI.Button(new Rect(0,30,100,30),"load"))
    {
        for(int i =0;i<str.Length;i++)
        {
            StartCoroutine(LoadAsset(str[i],i));
        }
    }
    IEnumerator LoadAsset(string name,int i)
    {
        WWW w = new WWW("file://"+Application.persistentDataPath+"/"+name+".AssetBundle");
        yield return w;
        Instantiate(w.assetBundle.mainAsset,new Vector3(i*2,0,0),Quaternion.identity);
        w.assetBundle.Unload(false);
    }

    注意事项:

    1、pc测试 需要修改IP地址,本地测试改为127.0.0.1 同时Application.persistentDataPath最好做修改,因为在pc上Application.persistentDataPath:C:Users用户名AppDataLocalLowDefaultCompanyu3d工程名,可以下载到此文件夹下,但是加载的时候会报错,没什么权限之类的

    2、android上需要stripping level设置为Disabled

  • 相关阅读:
    前端之JavaScript
    前端之CSS
    前端之HTML
    编程总结
    线程
    锁机制,信号机制,事件机制
    并发编程
    struct
    linux查看端口
    vue页面跳转传参
  • 原文地址:https://www.cnblogs.com/U-tansuo/p/unity3d_Threading_AsyDown_HTTP.html
Copyright © 2011-2022 走看看