Unity WWW强力封装

这个的分享个人认为还是很有用的,unity的WWW类的扩展,可以更容易的操作请求头,例如cookie等,并且加入了自定义时间长短的超时的控制。

另外,移除了调用方代码对协程的依赖。例如进度等可以通过封装类来更加的面向对象的获取。

请求完成通过委托回调来触发。

其中的中文注释被同事搞乱码了。我改回来了一部分成英文,将就看吧。。。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Text;

/// <summary>
/// Unity WWW extends,don`t support chinese url
/// yx
/// </summary>
public class WWWEX {
    /// <summary>
    /// ios backup to cloud flag
    /// </summary>
    public static bool IosBackUp = false;
    public static int max = 10;
    public static bool Log = false;
    public const float DefaultTimeout = 5;//s
    static List<WWW> pool = new List<WWW>(max);

    WWW instwww = null;
    public float Progress {
        get {
            if (instwww == null)
                return 0;
            else {
                return instwww.progress;
            }
        }
    }
    public bool IsDown {
        get {
            if (instwww == null)
                return false;
            else {
                return instwww.isDone;
            }
        }
    }
    /// <summary>
    /// set a function to make cache path,it`s not necessary
    /// </summary>
    public Func<string, string> CachePathInterface;

    private bool disposed = false;
    public bool IsDisposed {
        get {
            return disposed;
        }
    }
    public WWWEX() {
        CachePathInterface = GetCacheURIEX;
    }
    /// <summary>
    /// if you want to save file to path with your mind,use this constructor to new a inst
    /// </summary>
    /// <param name="RewindCachePath"></param>
    public WWWEX(Func<string, string> RewindCachePath) {
        CachePathInterface = RewindCachePath;
    }
    /// <summary>
    /// load from cache or web,arg:version`s usage is like www;
    /// </summary>
    public void LoadFromCacheOrDownload(string url, string version, Action<WWWResult> callback, float timeout = DefaultTimeout) {
        disposed = false;
        CoroutineWrapper.EXEE(_LoadFromCacheOrDownload, url, version, callback,timeout);
    }
    private IEnumerator _LoadFromCacheOrDownload(object[] p) {
        while (pool.Count >= max) {
            if (disposed) {
                yield break;
            }
            yield return new WaitForEndOfFrame();
        }
        
        string url = (string)p[0];
        string verson = p[1].ToString();
        float timeout = (float)p[3];

        string sb = CachePathInterface(url);

        bool cached = File.Exists(sb) && CompareVersion(sb,verson);
        WWW t_instwww = null;
        if (cached) {
            //Debug.Log("load from local");
            t_instwww = new WWW("file:///" + sb);
        } else {
            //Debug.Log("load from www");
            t_instwww = new WWW(url);
        }
        yield return new WaitForEndOfFrame();
        instwww = t_instwww;
        pool.Add(t_instwww);
        float curTime = 0;
        while (t_instwww != null && !t_instwww.isDone) {
            if (disposed) {//break
                pool.Remove(t_instwww);
                //t_instwww.Dispose();
                t_instwww = null;
                instwww = null;
                yield break;
            }
            else if (curTime > timeout && t_instwww.progress <= 0) {//timeout
                pool.Remove(t_instwww);
                t_instwww = null;
                instwww = null;
                break;
            }
            yield return new WaitForEndOfFrame();
            curTime += Time.deltaTime;
        }
        if (t_instwww == null) {
            var result = new WWWResult(null);
            result.SetOverrideError("timeout");
            if (p[2] != null)
                ((Action<WWWResult>)p[2])(result);
            yield break;
        }
        pool.Remove(t_instwww);
        if (!cached && t_instwww.error == null) {
            //Debug.Log("??????棺" + sb);
            if (!Directory.Exists(Path.GetDirectoryName(sb)))
                Directory.CreateDirectory(Path.GetDirectoryName(sb));
            File.WriteAllBytes(sb, t_instwww.bytes);
            string metaPath = CreateMetaFile(sb, verson);
#if UNITY_IPHONE
            if (Application.platform == RuntimePlatform.IPhonePlayer && !IosBackUp) {
		        UnityEngine.iOS.Device.SetNoBackupFlag(sb);
            }
            UnityEngine.iOS.Device.SetNoBackupFlag(metaPath);
#endif
        }
        if (Log) {
            LogWWW(t_instwww);
        }
        if (p[2] != null)
            ((Action<WWWResult>)p[2])(new WWWResult(t_instwww));
    }
    /// <summary>
    /// www
    /// </summary>
    public void www(string url, WWWForm form, Action<WWWResult> callback,float timeout = DefaultTimeout) {
        disposed = false;
        CoroutineWrapper.EXEE(_www, url, form, callback,timeout);
    }
    public void www(string url, byte[] data, Dictionary<string, string> header, Action<WWWResult> callback,float timeout = DefaultTimeout) {
        disposed = false;
        CoroutineWrapper.EXEE(_wwwWithHeader, url, data,header, callback,timeout);
    }
    private IEnumerator _www(object[] p) {
        while (pool.Count >= max) {
            yield return new WaitForEndOfFrame();
            if (disposed) {
                yield break;
            }
        }
        WWW t_instwww = null;
        if (p[1] == null)
            t_instwww = new WWW((string)p[0]);
        else
            t_instwww = new WWW((string)p[0], p[1] as WWWForm);
        float timeout = (float)p[3];
        yield return new WaitForEndOfFrame();
        instwww = t_instwww;
        pool.Add(t_instwww);
        float curTime = 0;
        while (t_instwww != null && !t_instwww.isDone) {
            if (disposed) {
                pool.Remove(t_instwww);
                //t_instwww.Dispose();
                t_instwww = null;
                instwww = null;
                yield break;
            }
            else if (curTime > timeout && t_instwww.bytesDownloaded == 0) {
                pool.Remove(t_instwww);
                t_instwww = null;
                instwww = null;
                break;
            }
            yield return new WaitForEndOfFrame();
            curTime += Time.deltaTime;
        }
        
        if (t_instwww == null) {
            var result = new WWWResult(null);
            result.SetOverrideError("timeout");
            if (p[2] != null)
                ((Action<WWWResult>)p[2])(result);
            yield break;
        }
        pool.Remove(t_instwww);
        if (Log) {
            LogWWW(t_instwww);
        }
        if (p[2] != null)
            ((Action<WWWResult>)p[2])(new WWWResult(t_instwww));
    }
    private IEnumerator _wwwWithHeader(object[] p) {
        while (pool.Count >= max) {
            yield return new WaitForEndOfFrame();
            if (disposed) {
                yield break;
            }
        }
        WWW t_instwww = new WWW((string)p[0], p[1] as byte[], p[2] as Dictionary<string, string>);
        float timeout = (float)p[4];
        yield return new WaitForEndOfFrame();
        instwww = t_instwww;
        pool.Add(t_instwww);
        float curTime = 0;
        while (t_instwww != null && !t_instwww.isDone) {
            if (disposed) {
                pool.Remove(t_instwww);
                //t_instwww.Dispose();
                t_instwww = null;
                instwww = null;
                yield break;
            }
            else if (curTime > timeout && t_instwww.progress <= 0) {
                pool.Remove(t_instwww);
                t_instwww = null;
                instwww = null;
                break;
            }
            yield return new WaitForEndOfFrame();
            curTime += Time.deltaTime;
        }
        if (t_instwww == null) {
            if (p[3] != null) {
                var result = new WWWResult(null);
                result.SetOverrideError("timeout");
                ((Action<WWWResult>)p[3])(result);
            }
            yield break;
        }
        pool.Remove(t_instwww);
        if (Log) {
            LogWWW(t_instwww);
        }
        if (p[3] != null)
            ((Action<WWWResult>)p[3])(new WWWResult(t_instwww));
    }
    /// <summary>
    /// cache a file
    /// </summary>
    public void CacheIt(string url, string version, Action<bool, string> callback,float timeout = DefaultTimeout) {
        disposed = false;
        CoroutineWrapper.EXEE(_CacheIt, url, version, callback,timeout);
    }
    private IEnumerator _CacheIt(object[] p) {
        while (pool.Count >= max) {
            yield return new WaitForEndOfFrame();
            if (disposed) {
                yield break;
            }
        }
        string url = (string)p[0];
        string verson = p[1].ToString();
        float timeout = (float)p[3];

        if (url.EndsWith("/")) {
            if (p[2] != null)
                ((Action<bool, string>)p[2])(false, "url is dir");
            yield break;
        }
        string sb = CachePathInterface(url);
        bool success = true;

        bool cached = File.Exists(sb) && CompareVersion(sb, verson);

        if (cached) {
            ;
        } else {
            //Debug.Log("load from www");
            WWW t_instwww = new WWW(url);
            yield return new WaitForEndOfFrame();
            instwww = t_instwww;
            pool.Add(t_instwww);
            float curTime = 0;
            while (t_instwww != null && !t_instwww.isDone) {
                if (disposed) {
                    pool.Remove(t_instwww);
                    //t_instwww.Dispose();
                    t_instwww = null;
                    instwww = null;
                    yield break;
                }
                else if (curTime > timeout && t_instwww.progress <= 0) {
                    pool.Remove(t_instwww);
                    t_instwww = null;
                    instwww = null;
                    success = false;
                    sb = "timeout";
                    break;
                }
                yield return new WaitForEndOfFrame();
                curTime += Time.deltaTime;
            }
            
            if (t_instwww == null) {
                if (p[2] != null)
                    ((Action<bool, string>)p[2])(success, sb);
                yield break;
            }
            pool.Remove(t_instwww);
            if (!cached && t_instwww.error == null) {
                if (!Directory.Exists(Path.GetDirectoryName(sb)))
                    Directory.CreateDirectory(Path.GetDirectoryName(sb));
                File.WriteAllBytes(sb, t_instwww.bytes);
                string metaPath = CreateMetaFile(sb, verson);
#if UNITY_IPHONE
                if (Application.platform == RuntimePlatform.IPhonePlayer && !IosBackUp) {
		            UnityEngine.iOS.Device.SetNoBackupFlag(sb);
                }
                UnityEngine.iOS.Device.SetNoBackupFlag(metaPath);
#endif
            }
            else if (t_instwww.error != null) {
                success = false;
                sb = t_instwww.error;
            }
            if (Log) {
                LogWWW(t_instwww);
            }
        }
        if (p[2] != null)
            ((Action<bool,string>)p[2])(success,sb);
    }

    public void Dispose() {
        disposed = true;
        //if (instwww!=null) {
        //    //instwww.Dispose();
        //    instwww = null;
        //}
    }
    public bool CheckCache(string weburl) {
        string fpath = this.CachePathInterface(weburl);
        return File.Exists(fpath);
    }
    /// <summary>
    /// get cache path with a certain url
    /// you should use GetCacheURIEX preferred
    /// </summary>
    public static string GetCacheURI(string weburl) {
        StringBuilder sb = new StringBuilder(weburl);
        int i = sb.ToString().IndexOf('?');
        if (i >= 0)
            sb.Remove(i, sb.Length - i);
        sb.Replace("http://", "").Replace(":","/").Replace("/", "+").Replace("\\", "+");
        string ffilename = Path.GetFileNameWithoutExtension(sb.ToString());
        //
        string mapedName = MapStr(ffilename,0,ffilename.LastIndexOf('+'),'+','.');
        int t_index = ffilename.LastIndexOf('+');
        t_index = t_index>=0? t_index:0;
        string fn = ffilename.Substring(t_index);
        mapedName += Chinese2UniCode(fn, 0, fn.Length);
        sb.Replace(ffilename, mapedName);
        //
        sb.Insert(0, Application.persistentDataPath + "/wwwcache/");
        return sb.ToString();
    }
    /// <summary>
    /// get cache path with a certain url
    /// </summary>
    public static string GetCacheURIEX(string weburl) {
        string sb = GetCacheURI(weburl);
        int i = sb.LastIndexOf('+');
        string path, name;

        path = sb.Substring(0, i);
        name = sb.Substring(i + 1);

        sb = path + "/" + name;
        return sb;
    }
    private static string MapStr(string o,int start,int end,params char[] ignore) {
        StringBuilder sb = new StringBuilder(o.Substring(0,start));
        for (int i = start; i < end; i++) {
            if(ignore!=null){
                char t = Array.Find<char>(ignore, n => { return n.Equals(o[i]); });
                if (t == '\0') {
                    string c;
                    if (o[i] >= 0 && o[i] <= 127)
                        c = Convert.ToChar((Convert.ToInt32(o[i]) + i) % 26 + 97).ToString();
                    else {
                        c = o[i].ToString();
                        Debug.Log(c);
                    }
                    sb.Append(c);
                } else
                    sb.Append(t);
            } else {
                string c;
                if (o[i] >= 0 && o[i] <= 127)
                    c = Convert.ToChar((Convert.ToInt32(o[i]) + i) % 26 + 97).ToString();
                else
                    c = o[i].ToString();
                sb.Append(c);
            }
        }
        return sb.ToString();
    }
    /// <summary>
    /// this function has some bug,so class doesn`t support chinese in fact
    /// </summary>
    /// <returns></returns>
    private static string Chinese2UniCode(string o,int start,int end,params char[] ignore) {
        StringBuilder sb = new StringBuilder(o.Substring(0, start));
        for (int i = start; i < end; i++) {
            if (ignore != null) {
                char t = Array.Find<char>(ignore, n => { return n.Equals(o[i]); });
                if (t == '\0') {
                    string c;
                    if (o[i] >= 0 && o[i] <= 127)
                        c = o[i].ToString();
                    else
                        c = string.Format("U{0:x4}", Convert.ToInt32(o[i]));
                    sb.Append(c);
                } else
                    sb.Append(t);
            } else {
                string c;
                if (o[i] >= 0 && o[i] <= 127)
                    c = o[i].ToString();
                else
                    c = string.Format("U{0:x4}", Convert.ToInt32(o[i]));
                sb.Append(c);
            }
        }
        return sb.ToString();
    }
    /// <summary>
    /// create a meta file to record file info
    /// </summary>
    private static string CreateMetaFile(string FilePath,string version) {
        string metaFilePath = FilePath + ".yxMeta";
        var table = HashtableEX.Construct(
            "version",version
            );
        string serialize = table.toJson();
        serialize = XORStr(serialize, Path.GetFileName(FilePath));
        FileStream fs = new FileStream(metaFilePath, FileMode.Create);
        StreamWriter sw = new StreamWriter(fs);
        sw.Write(serialize);
        sw.Flush();
        sw.Close();
        return metaFilePath;
    }
    /// <summary>
    /// 
    /// </summary>
    private static Hashtable LoadMetaFile(string FilePath) {
        string metaFilePath = FilePath + ".yxMeta";
        if (!File.Exists(metaFilePath)) {
            return new Hashtable();
        }
        StreamReader sr = new StreamReader(metaFilePath);
        string serialize = sr.ReadToEnd();
        sr.Close();
        serialize = XORStr(serialize, Path.GetFileName(FilePath));
        try {
            return serialize.hashtableFromJson();
        }
        catch {
            return new Hashtable();
        }
    }
    /// <summary>
    /// 
    /// </summary>
    private static string GetVersionFromMeta(string FilePath) {
        var table = LoadMetaFile(FilePath);
        return table.SGet<string>("version");
    }
    /// <summary>
    /// 
    /// </summary>
    private static bool CompareVersion(string FilePath,string remoteVersion) {
        return GetVersionFromMeta(FilePath) == remoteVersion;
    }
    /// <summary>
    /// check file status
    /// </summary>
    /// <returns>0:normal    1:local ahead       -1:remote ahead      -2:local not exsit      -3:meta error</returns>
    public static int CheckFile(string URL, string RemoteVersion,bool EX = false) {
        string FilePath;
        if (!EX)
            FilePath = GetCacheURI(URL);
        else
            FilePath = GetCacheURIEX(URL);
        if (!File.Exists(FilePath)) {
            return -2;
        }
        string local = GetVersionFromMeta(FilePath);
        if (local == RemoteVersion) {
            return 0;
        }
        else {
            try {
                int i_local = int.Parse(local);
                int i_remote = int.Parse(RemoteVersion);
                if (i_local<=i_remote) {
                    return -1;
                }
                else {
                    return 1;
                }
            }
            catch {
                return -3;
            }
        }
    }
    /// <summary>
    /// xor
    /// </summary>
    private static string XORStr(string p, string key) {
        byte[] ks = Encoding.UTF8.GetBytes(key);
        int kl = ks.Length;
        byte[] bs = Encoding.UTF8.GetBytes(p);
        for (int i = 0; i < bs.Length; i++) {
            bs[i] = (byte)(bs[i] ^ ks[i % kl]);
        }
        return Encoding.UTF8.GetString(bs);
    }
    private static void LogWWW(WWW www) {
        Debug.Log(www.url);
        if (www.error!=null)
        {
            Debug.Log(www.error);
        }
        var by = www.bytes;
        if (by.Length <= 10240) {//10k
            Debug.Log(www.text);
        }
        return;
        //follow code has some bug in ios,and it just want to write a log,so I haven`t cost time to fix it
        if (www==null || www.error == null){
		     return;
	    }
        StringBuilder sb = new StringBuilder();
        sb.AppendLine();
        sb.AppendLine(string.Format("-------{0}-------", System.DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")));
        sb.AppendLine("url:"+www.url);
        var rspHead = www.responseHeaders;
        sb.AppendLine("responseHeader:");
        foreach (var i in rspHead) {
            sb.AppendLine("  "+i.Key+""+i.Value);
        }
        sb.AppendLine("error:"+www.error);
        var b = www.bytes;
        if (b.Length<=10240) {//????????10k
            sb.AppendLine("text:"+www.text);
        }
        else {
            byte[] trim = new byte[40];
            Array.Copy(b,trim,trim.Length);
            sb.AppendLine(string.Format("text: ???????{0},???????????????,?40????:{1}",b.Length,Encoding.UTF8.GetString(trim)));
        }
        sb.AppendLine();
        File.AppendAllText(Application.persistentDataPath+"/WWWError.log", sb.ToString());
    }
    public static void ClearCache(string URL,bool EX) {
        string FilePath;
        if (!EX)
            FilePath = GetCacheURI(URL);
        else
            FilePath = GetCacheURIEX(URL);
        string metaPath = FilePath + ".yxMeta";
        if (File.Exists(FilePath)) {
            File.Delete(FilePath);
        }
        if (File.Exists(metaPath)) {
            File.Delete(metaPath);
        }
    }
    public static void ClearCache(string FilePath) {
        string metaPath = FilePath + ".yxMeta";
        if (File.Exists(FilePath)) {
            File.Delete(FilePath);
        }
        if (File.Exists(metaPath)) {
            File.Delete(metaPath);
        }
    }
    /// <summary>
    /// a wrapper of a WWW inst which has done
    /// </summary>
    public class WWWResult {
        WWW wwwInst;
        string overrideError = null;
        public WWWResult(WWW www) {
            wwwInst = www;
        }
        public void SetOverrideError(string error) {
            overrideError = error;
        }
        public AssetBundle assetBundle {
            get {
                if (wwwInst!=null) {
                    return wwwInst.assetBundle;
                }
                else {
                    return null;
                }
            }
        }
        public AudioClip audioClip {
            get {
                if (wwwInst != null) {
                    return wwwInst.audioClip;
                }
                else {
                    return null;
                }
            }
        }
        public byte[] bytes {
            get {
                if (wwwInst != null) {
                    return wwwInst.bytes;
                }
                else {
                    return null;
                }
            }
        }
        public string error {
            get {
                if (wwwInst != null) {
                    if (!overrideError.IsNullOrEmpty()) {
                        return overrideError;
                    }
                    return wwwInst.error;
                }
                else {
                    return overrideError;
                }
            }
        }
        public Dictionary<string, string> responseHeaders {
            get {
                if (wwwInst != null) {
                    return wwwInst.responseHeaders;
                }
                else {
                    return null;
                }
            }
        }
        public int size {
            get {
                if (wwwInst != null) {
                    return wwwInst.size;
                }
                else {
                    return -1;
                }
            }
        }
        public string text {
            get {
                if (wwwInst != null) {
                    if (!overrideError.IsNullOrEmpty()) {
                        return overrideError;
                    }
                    return wwwInst.text;
                }
                else {
                    return overrideError;
                }
            }
        }
        public Texture2D texture {
            get {
                if (wwwInst != null) {
                    return wwwInst.texture;
                }
                else {
                    return null;
                }
            }
        }
        public Texture2D textureNonReadable {
            get {
                if (wwwInst != null) {
                    return wwwInst.textureNonReadable;
                }
                else {
                    return null;
                }
            }
        }
        public string url {
            get {
                if (wwwInst != null) {
                    return wwwInst.url;
                }
                else {
                    return null;
                }
            }
        }
        public AudioClip GetAudioClip(bool threeD) {
            if (wwwInst != null) {
                return wwwInst.GetAudioClip(threeD);
            }
            else {
                return null;
            }
        }
        public AudioClip GetAudioClip(bool threeD, bool stream) {
            if (wwwInst != null) {
                return wwwInst.GetAudioClip(threeD,stream);
            }
            else {
                return null;
            }
        }
        public AudioClip GetAudioClip(bool threeD, bool stream, AudioType audioType) {
            if (wwwInst != null) {
                return wwwInst.GetAudioClip(threeD, stream, audioType);
            }
            else {
                return null;
            }
        }
        public AudioClip GetAudioClipCompressed() {
            if (wwwInst != null) {
                return wwwInst.GetAudioClipCompressed();
            }
            else {
                return null;
            }
        }
        public AudioClip GetAudioClipCompressed(bool threeD) {
            if (wwwInst != null) {
                return wwwInst.GetAudioClipCompressed(threeD);
            }
            else {
                return null;
            }
        }
        public AudioClip GetAudioClipCompressed(bool threeD, AudioType audioType) {
            if (wwwInst != null) {
                return wwwInst.GetAudioClipCompressed(threeD, audioType);
            }
            else {
                return null;
            }
        }
        public void LoadImageIntoTexture(Texture2D tex) {
            if (wwwInst != null) {
                wwwInst.LoadImageIntoTexture(tex);
            }
            else {
                return;
            }
        }
    }
}

依赖另一个脚本来转移协程:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Reflection;
/// <summary>
/// Э?????д???
/// </summary>
public class CoroutineWrapper : MonoBehaviour {
    #region ????
    static CoroutineWrapper inst;
    private readonly static object mutex = new object();
    public static CoroutineWrapper Inst {
        get {
            if (inst == null) {
                var obj = new GameObject("CoroutineWrapper");
                DontDestroyOnLoad(obj);
                inst = obj.AddComponent<CoroutineWrapper>();
                inst.Init();
            }
            return inst;
        }
    }
    void Init() {
        inst = this;
    }
    #endregion
    /// <summary>
    /// ????????????
    /// </summary>
    /// <param name="frames"></param>
    /// <param name="ev"></param>
    /// <returns></returns>
    public IEnumerator ExeDelay(int frames,Action ev) {
        for (int i = 0; i < frames;i++ ) {
            yield return new WaitForEndOfFrame();
        }
        ev();
    }
    /// <summary>
    /// ????????????
    /// </summary>
    /// <param name="sec"></param>
    /// <param name="ev"></param>
    /// <returns></returns>
    public IEnumerator ExeDelayS(float sec, Action ev) {
        yield return new WaitForSeconds(sec);
        ev();;
    }
    /// <summary>
    /// ????????????
    /// </summary>
    /// <param name="sec"></param>
    /// <param name="ev"></param>
    public static void EXES(float sec, Action ev) {
        inst.StartCoroutine(inst.ExeDelayS(sec,ev));
    }
    /// <summary>
    /// ????????????
    /// </summary>
    /// <param name="frames"></param>
    /// <param name="ev"></param>
    public static void EXEF(int frames, Action ev) {
        inst.StartCoroutine(inst.ExeDelay(frames, ev));
    }
    /// <summary>
    /// ?????????Э??
    /// </summary>
    /// <param name="ien">Э?????</param>
    public static void EXEE(Func<IEnumerator> ien) {
        inst.StartCoroutine(ien());
    }
    /// <summary>
    ///
    /// </summary>
    /// <param name="ien">Э?????</param>
    /// <param name="p">??????</param>
    public static void EXEE(Func<object[],IEnumerator> ien,params object[] p) {
        inst.StartCoroutine(ien(p));
    }
    /// <summary>
    /// call fun with any type args,function must be public
    /// </summary>
    /// <param name="t"></param>
    /// <param name="FuncName"></param>
    /// <param name="inst"></param>
    /// <param name="p"></param>
    public static void ReflectCallCoroutine(Type t, string FuncName,object inst, params object[] p) {
        Type[] pt = null;
        if (p!=null) {
            pt = new Type[p.Length];
            for (int i = 0; i < pt.Length; i++) {
                pt[i] = p[i].GetType();
            }
        }
        MethodInfo method;
        if (pt!=null) {
            method = t.GetMethod(FuncName,pt);
        } else {
            method = t.GetMethod(FuncName);
        }
        if (method == null) {
            Debug.LogFormat("can`t find method {0} with give params",FuncName);
            return;
        }
        var u3dCoroutineCaller = inst.GetType().GetMethod("StartCoroutine", new Type[] { typeof(IEnumerator) });
        if (u3dCoroutineCaller == null) {
            Debug.Log("can`t find u3d coroutine caller");
            return;
        }
        u3dCoroutineCaller.Invoke(inst, new object[]{method.Invoke(inst, p)});
    }
    /// <summary>
    /// this action will be called per frame
    /// </summary>
    public event Action OnPerFrame;
    void Update() {
        if (OnPerFrame != null)
            OnPerFrame();
    }
}

好了,举个栗子:

先初始化一下工具:

void Awake() {
    var t = CoroutineWrapper.Inst;
}
再开始你的http访问,例如下面这个,是提交评论

public WWWEX CommentProjImpl(string uid, string comment, Action<WWWEX.WWWResult> callback) {
        string url = "xxx";
        WWWEX wex = new WWWEX();
        WWWForm form = new WWWForm();
        form.AddField("uniqid",uid);
        form.AddField("content", comment);
        wex.www(url, form.data, MakeHeader(), callback);//MakeHeader是一个生成一些请求头字段的方法,生成的一个Dictionary<string, string>,可以不管
        return wex;
    }
然后,这个函数就返回了一个WWWEX的实例,要获取进度之类的就是可以通过这个实例的成员去访问。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值