Unity WWW强力封装

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

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

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

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

[csharp]  view plain  copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. using System;  
  5. using System.IO;  
  6. using System.Text;  
  7.   
  8. /// <summary>  
  9. /// Unity WWW extends,don`t support chinese url  
  10. /// yx  
  11. /// </summary>  
  12. public class WWWEX {  
  13.     /// <summary>  
  14.     /// ios backup to cloud flag  
  15.     /// </summary>  
  16.     public static bool IosBackUp = false;  
  17.     public static int max = 10;  
  18.     public static bool Log = false;  
  19.     public const float DefaultTimeout = 5;//s  
  20.     static List<WWW> pool = new List<WWW>(max);  
  21.   
  22.     WWW instwww = null;  
  23.     public float Progress {  
  24.         get {  
  25.             if (instwww == null)  
  26.                 return 0;  
  27.             else {  
  28.                 return instwww.progress;  
  29.             }  
  30.         }  
  31.     }  
  32.     public bool IsDown {  
  33.         get {  
  34.             if (instwww == null)  
  35.                 return false;  
  36.             else {  
  37.                 return instwww.isDone;  
  38.             }  
  39.         }  
  40.     }  
  41.     /// <summary>  
  42.     /// set a function to make cache path,it`s not necessary  
  43.     /// </summary>  
  44.     public Func<stringstring> CachePathInterface;  
  45.   
  46.     private bool disposed = false;  
  47.     public bool IsDisposed {  
  48.         get {  
  49.             return disposed;  
  50.         }  
  51.     }  
  52.     public WWWEX() {  
  53.         CachePathInterface = GetCacheURIEX;  
  54.     }  
  55.     /// <summary>  
  56.     /// if you want to save file to path with your mind,use this constructor to new a inst  
  57.     /// </summary>  
  58.     /// <param name="RewindCachePath"></param>  
  59.     public WWWEX(Func<stringstring> RewindCachePath) {  
  60.         CachePathInterface = RewindCachePath;  
  61.     }  
  62.     /// <summary>  
  63.     /// load from cache or web,arg:version`s usage is like www;  
  64.     /// </summary>  
  65.     public void LoadFromCacheOrDownload(string url, string version, Action<WWWResult> callback, float timeout = DefaultTimeout) {  
  66.         disposed = false;  
  67.         CoroutineWrapper.EXEE(_LoadFromCacheOrDownload, url, version, callback,timeout);  
  68.     }  
  69.     private IEnumerator _LoadFromCacheOrDownload(object[] p) {  
  70.         while (pool.Count >= max) {  
  71.             if (disposed) {  
  72.                 yield break;  
  73.             }  
  74.             yield return new WaitForEndOfFrame();  
  75.         }  
  76.           
  77.         string url = (string)p[0];  
  78.         string verson = p[1].ToString();  
  79.         float timeout = (float)p[3];  
  80.   
  81.         string sb = CachePathInterface(url);  
  82.   
  83.         bool cached = File.Exists(sb) && CompareVersion(sb,verson);  
  84.         WWW t_instwww = null;  
  85.         if (cached) {  
  86.             //Debug.Log("load from local");  
  87.             t_instwww = new WWW("file:///" + sb);  
  88.         } else {  
  89.             //Debug.Log("load from www");  
  90.             t_instwww = new WWW(url);  
  91.         }  
  92.         yield return new WaitForEndOfFrame();  
  93.         instwww = t_instwww;  
  94.         pool.Add(t_instwww);  
  95.         float curTime = 0;  
  96.         while (t_instwww != null && !t_instwww.isDone) {  
  97.             if (disposed) {//break  
  98.                 pool.Remove(t_instwww);  
  99.                 //t_instwww.Dispose();  
  100.                 t_instwww = null;  
  101.                 instwww = null;  
  102.                 yield break;  
  103.             }  
  104.             else if (curTime > timeout && t_instwww.progress <= 0) {//timeout  
  105.                 pool.Remove(t_instwww);  
  106.                 t_instwww = null;  
  107.                 instwww = null;  
  108.                 break;  
  109.             }  
  110.             yield return new WaitForEndOfFrame();  
  111.             curTime += Time.deltaTime;  
  112.         }  
  113.         if (t_instwww == null) {  
  114.             var result = new WWWResult(null);  
  115.             result.SetOverrideError("timeout");  
  116.             if (p[2] != null)  
  117.                 ((Action<WWWResult>)p[2])(result);  
  118.             yield break;  
  119.         }  
  120.         pool.Remove(t_instwww);  
  121.         if (!cached && t_instwww.error == null) {  
  122.             //Debug.Log("??????棺" + sb);  
  123.             if (!Directory.Exists(Path.GetDirectoryName(sb)))  
  124.                 Directory.CreateDirectory(Path.GetDirectoryName(sb));  
  125.             File.WriteAllBytes(sb, t_instwww.bytes);  
  126.             string metaPath = CreateMetaFile(sb, verson);  
  127. #if UNITY_IPHONE  
  128.             if (Application.platform == RuntimePlatform.IPhonePlayer && !IosBackUp) {  
  129.                 UnityEngine.iOS.Device.SetNoBackupFlag(sb);  
  130.             }  
  131.             UnityEngine.iOS.Device.SetNoBackupFlag(metaPath);  
  132. #endif  
  133.         }  
  134.         if (Log) {  
  135.             LogWWW(t_instwww);  
  136.         }  
  137.         if (p[2] != null)  
  138.             ((Action<WWWResult>)p[2])(new WWWResult(t_instwww));  
  139.     }  
  140.     /// <summary>  
  141.     /// www  
  142.     /// </summary>  
  143.     public void www(string url, WWWForm form, Action<WWWResult> callback,float timeout = DefaultTimeout) {  
  144.         disposed = false;  
  145.         CoroutineWrapper.EXEE(_www, url, form, callback,timeout);  
  146.     }  
  147.     public void www(string url, byte[] data, Dictionary<stringstring> header, Action<WWWResult> callback,float timeout = DefaultTimeout) {  
  148.         disposed = false;  
  149.         CoroutineWrapper.EXEE(_wwwWithHeader, url, data,header, callback,timeout);  
  150.     }  
  151.     private IEnumerator _www(object[] p) {  
  152.         while (pool.Count >= max) {  
  153.             yield return new WaitForEndOfFrame();  
  154.             if (disposed) {  
  155.                 yield break;  
  156.             }  
  157.         }  
  158.         WWW t_instwww = null;  
  159.         if (p[1] == null)  
  160.             t_instwww = new WWW((string)p[0]);  
  161.         else  
  162.             t_instwww = new WWW((string)p[0], p[1] as WWWForm);  
  163.         float timeout = (float)p[3];  
  164.         yield return new WaitForEndOfFrame();  
  165.         instwww = t_instwww;  
  166.         pool.Add(t_instwww);  
  167.         float curTime = 0;  
  168.         while (t_instwww != null && !t_instwww.isDone) {  
  169.             if (disposed) {  
  170.                 pool.Remove(t_instwww);  
  171.                 //t_instwww.Dispose();  
  172.                 t_instwww = null;  
  173.                 instwww = null;  
  174.                 yield break;  
  175.             }  
  176.             else if (curTime > timeout && t_instwww.bytesDownloaded == 0) {  
  177.                 pool.Remove(t_instwww);  
  178.                 t_instwww = null;  
  179.                 instwww = null;  
  180.                 break;  
  181.             }  
  182.             yield return new WaitForEndOfFrame();  
  183.             curTime += Time.deltaTime;  
  184.         }  
  185.           
  186.         if (t_instwww == null) {  
  187.             var result = new WWWResult(null);  
  188.             result.SetOverrideError("timeout");  
  189.             if (p[2] != null)  
  190.                 ((Action<WWWResult>)p[2])(result);  
  191.             yield break;  
  192.         }  
  193.         pool.Remove(t_instwww);  
  194.         if (Log) {  
  195.             LogWWW(t_instwww);  
  196.         }  
  197.         if (p[2] != null)  
  198.             ((Action<WWWResult>)p[2])(new WWWResult(t_instwww));  
  199.     }  
  200.     private IEnumerator _wwwWithHeader(object[] p) {  
  201.         while (pool.Count >= max) {  
  202.             yield return new WaitForEndOfFrame();  
  203.             if (disposed) {  
  204.                 yield break;  
  205.             }  
  206.         }  
  207.         WWW t_instwww = new WWW((string)p[0], p[1] as byte[], p[2] as Dictionary<stringstring>);  
  208.         float timeout = (float)p[4];  
  209.         yield return new WaitForEndOfFrame();  
  210.         instwww = t_instwww;  
  211.         pool.Add(t_instwww);  
  212.         float curTime = 0;  
  213.         while (t_instwww != null && !t_instwww.isDone) {  
  214.             if (disposed) {  
  215.                 pool.Remove(t_instwww);  
  216.                 //t_instwww.Dispose();  
  217.                 t_instwww = null;  
  218.                 instwww = null;  
  219.                 yield break;  
  220.             }  
  221.             else if (curTime > timeout && t_instwww.progress <= 0) {  
  222.                 pool.Remove(t_instwww);  
  223.                 t_instwww = null;  
  224.                 instwww = null;  
  225.                 break;  
  226.             }  
  227.             yield return new WaitForEndOfFrame();  
  228.             curTime += Time.deltaTime;  
  229.         }  
  230.         if (t_instwww == null) {  
  231.             if (p[3] != null) {  
  232.                 var result = new WWWResult(null);  
  233.                 result.SetOverrideError("timeout");  
  234.                 ((Action<WWWResult>)p[3])(result);  
  235.             }  
  236.             yield break;  
  237.         }  
  238.         pool.Remove(t_instwww);  
  239.         if (Log) {  
  240.             LogWWW(t_instwww);  
  241.         }  
  242.         if (p[3] != null)  
  243.             ((Action<WWWResult>)p[3])(new WWWResult(t_instwww));  
  244.     }  
  245.     /// <summary>  
  246.     /// cache a file  
  247.     /// </summary>  
  248.     public void CacheIt(string url, string version, Action<boolstring> callback,float timeout = DefaultTimeout) {  
  249.         disposed = false;  
  250.         CoroutineWrapper.EXEE(_CacheIt, url, version, callback,timeout);  
  251.     }  
  252.     private IEnumerator _CacheIt(object[] p) {  
  253.         while (pool.Count >= max) {  
  254.             yield return new WaitForEndOfFrame();  
  255.             if (disposed) {  
  256.                 yield break;  
  257.             }  
  258.         }  
  259.         string url = (string)p[0];  
  260.         string verson = p[1].ToString();  
  261.         float timeout = (float)p[3];  
  262.   
  263.         if (url.EndsWith("/")) {  
  264.             if (p[2] != null)  
  265.                 ((Action<boolstring>)p[2])(false"url is dir");  
  266.             yield break;  
  267.         }  
  268.         string sb = CachePathInterface(url);  
  269.         bool success = true;  
  270.   
  271.         bool cached = File.Exists(sb) && CompareVersion(sb, verson);  
  272.   
  273.         if (cached) {  
  274.             ;  
  275.         } else {  
  276.             //Debug.Log("load from www");  
  277.             WWW t_instwww = new WWW(url);  
  278.             yield return new WaitForEndOfFrame();  
  279.             instwww = t_instwww;  
  280.             pool.Add(t_instwww);  
  281.             float curTime = 0;  
  282.             while (t_instwww != null && !t_instwww.isDone) {  
  283.                 if (disposed) {  
  284.                     pool.Remove(t_instwww);  
  285.                     //t_instwww.Dispose();  
  286.                     t_instwww = null;  
  287.                     instwww = null;  
  288.                     yield break;  
  289.                 }  
  290.                 else if (curTime > timeout && t_instwww.progress <= 0) {  
  291.                     pool.Remove(t_instwww);  
  292.                     t_instwww = null;  
  293.                     instwww = null;  
  294.                     success = false;  
  295.                     sb = "timeout";  
  296.                     break;  
  297.                 }  
  298.                 yield return new WaitForEndOfFrame();  
  299.                 curTime += Time.deltaTime;  
  300.             }  
  301.               
  302.             if (t_instwww == null) {  
  303.                 if (p[2] != null)  
  304.                     ((Action<boolstring>)p[2])(success, sb);  
  305.                 yield break;  
  306.             }  
  307.             pool.Remove(t_instwww);  
  308.             if (!cached && t_instwww.error == null) {  
  309.                 if (!Directory.Exists(Path.GetDirectoryName(sb)))  
  310.                     Directory.CreateDirectory(Path.GetDirectoryName(sb));  
  311.                 File.WriteAllBytes(sb, t_instwww.bytes);  
  312.                 string metaPath = CreateMetaFile(sb, verson);  
  313. #if UNITY_IPHONE  
  314.                 if (Application.platform == RuntimePlatform.IPhonePlayer && !IosBackUp) {  
  315.                     UnityEngine.iOS.Device.SetNoBackupFlag(sb);  
  316.                 }  
  317.                 UnityEngine.iOS.Device.SetNoBackupFlag(metaPath);  
  318. #endif  
  319.             }  
  320.             else if (t_instwww.error != null) {  
  321.                 success = false;  
  322.                 sb = t_instwww.error;  
  323.             }  
  324.             if (Log) {  
  325.                 LogWWW(t_instwww);  
  326.             }  
  327.         }  
  328.         if (p[2] != null)  
  329.             ((Action<bool,string>)p[2])(success,sb);  
  330.     }  
  331.   
  332.     public void Dispose() {  
  333.         disposed = true;  
  334.         //if (instwww!=null) {  
  335.         //    //instwww.Dispose();  
  336.         //    instwww = null;  
  337.         //}  
  338.     }  
  339.     public bool CheckCache(string weburl) {  
  340.         string fpath = this.CachePathInterface(weburl);  
  341.         return File.Exists(fpath);  
  342.     }  
  343.     /// <summary>  
  344.     /// get cache path with a certain url  
  345.     /// you should use GetCacheURIEX preferred  
  346.     /// </summary>  
  347.     public static string GetCacheURI(string weburl) {  
  348.         StringBuilder sb = new StringBuilder(weburl);  
  349.         int i = sb.ToString().IndexOf('?');  
  350.         if (i >= 0)  
  351.             sb.Remove(i, sb.Length - i);  
  352.         sb.Replace("http://""").Replace(":","/").Replace("/""+").Replace("\\", "+");  
  353.         string ffilename = Path.GetFileNameWithoutExtension(sb.ToString());  
  354.         //  
  355.         string mapedName = MapStr(ffilename,0,ffilename.LastIndexOf('+'),'+','.');  
  356.         int t_index = ffilename.LastIndexOf('+');  
  357.         t_index = t_index>=0? t_index:0;  
  358.         string fn = ffilename.Substring(t_index);  
  359.         mapedName += Chinese2UniCode(fn, 0, fn.Length);  
  360.         sb.Replace(ffilename, mapedName);  
  361.         //  
  362.         sb.Insert(0, Application.persistentDataPath + "/wwwcache/");  
  363.         return sb.ToString();  
  364.     }  
  365.     /// <summary>  
  366.     /// get cache path with a certain url  
  367.     /// </summary>  
  368.     public static string GetCacheURIEX(string weburl) {  
  369.         string sb = GetCacheURI(weburl);  
  370.         int i = sb.LastIndexOf('+');  
  371.         string path, name;  
  372.   
  373.         path = sb.Substring(0, i);  
  374.         name = sb.Substring(i + 1);  
  375.   
  376.         sb = path + "/" + name;  
  377.         return sb;  
  378.     }  
  379.     private static string MapStr(string o,int start,int end,params char[] ignore) {  
  380.         StringBuilder sb = new StringBuilder(o.Substring(0,start));  
  381.         for (int i = start; i < end; i++) {  
  382.             if(ignore!=null){  
  383.                 char t = Array.Find<char>(ignore, n => { return n.Equals(o[i]); });  
  384.                 if (t == '\0') {  
  385.                     string c;  
  386.                     if (o[i] >= 0 && o[i] <= 127)  
  387.                         c = Convert.ToChar((Convert.ToInt32(o[i]) + i) % 26 + 97).ToString();  
  388.                     else {  
  389.                         c = o[i].ToString();  
  390.                         Debug.Log(c);  
  391.                     }  
  392.                     sb.Append(c);  
  393.                 } else  
  394.                     sb.Append(t);  
  395.             } else {  
  396.                 string c;  
  397.                 if (o[i] >= 0 && o[i] <= 127)  
  398.                     c = Convert.ToChar((Convert.ToInt32(o[i]) + i) % 26 + 97).ToString();  
  399.                 else  
  400.                     c = o[i].ToString();  
  401.                 sb.Append(c);  
  402.             }  
  403.         }  
  404.         return sb.ToString();  
  405.     }  
  406.     /// <summary>  
  407.     /// this function has some bug,so class doesn`t support chinese in fact  
  408.     /// </summary>  
  409.     /// <returns></returns>  
  410.     private static string Chinese2UniCode(string o,int start,int end,params char[] ignore) {  
  411.         StringBuilder sb = new StringBuilder(o.Substring(0, start));  
  412.         for (int i = start; i < end; i++) {  
  413.             if (ignore != null) {  
  414.                 char t = Array.Find<char>(ignore, n => { return n.Equals(o[i]); });  
  415.                 if (t == '\0') {  
  416.                     string c;  
  417.                     if (o[i] >= 0 && o[i] <= 127)  
  418.                         c = o[i].ToString();  
  419.                     else  
  420.                         c = string.Format("U{0:x4}", Convert.ToInt32(o[i]));  
  421.                     sb.Append(c);  
  422.                 } else  
  423.                     sb.Append(t);  
  424.             } else {  
  425.                 string c;  
  426.                 if (o[i] >= 0 && o[i] <= 127)  
  427.                     c = o[i].ToString();  
  428.                 else  
  429.                     c = string.Format("U{0:x4}", Convert.ToInt32(o[i]));  
  430.                 sb.Append(c);  
  431.             }  
  432.         }  
  433.         return sb.ToString();  
  434.     }  
  435.     /// <summary>  
  436.     /// create a meta file to record file info  
  437.     /// </summary>  
  438.     private static string CreateMetaFile(string FilePath,string version) {  
  439.         string metaFilePath = FilePath + ".yxMeta";  
  440.         var table = HashtableEX.Construct(  
  441.             "version",version  
  442.             );  
  443.         string serialize = table.toJson();  
  444.         serialize = XORStr(serialize, Path.GetFileName(FilePath));  
  445.         FileStream fs = new FileStream(metaFilePath, FileMode.Create);  
  446.         StreamWriter sw = new StreamWriter(fs);  
  447.         sw.Write(serialize);  
  448.         sw.Flush();  
  449.         sw.Close();  
  450.         return metaFilePath;  
  451.     }  
  452.     /// <summary>  
  453.     ///   
  454.     /// </summary>  
  455.     private static Hashtable LoadMetaFile(string FilePath) {  
  456.         string metaFilePath = FilePath + ".yxMeta";  
  457.         if (!File.Exists(metaFilePath)) {  
  458.             return new Hashtable();  
  459.         }  
  460.         StreamReader sr = new StreamReader(metaFilePath);  
  461.         string serialize = sr.ReadToEnd();  
  462.         sr.Close();  
  463.         serialize = XORStr(serialize, Path.GetFileName(FilePath));  
  464.         try {  
  465.             return serialize.hashtableFromJson();  
  466.         }  
  467.         catch {  
  468.             return new Hashtable();  
  469.         }  
  470.     }  
  471.     /// <summary>  
  472.     ///   
  473.     /// </summary>  
  474.     private static string GetVersionFromMeta(string FilePath) {  
  475.         var table = LoadMetaFile(FilePath);  
  476.         return table.SGet<string>("version");  
  477.     }  
  478.     /// <summary>  
  479.     ///   
  480.     /// </summary>  
  481.     private static bool CompareVersion(string FilePath,string remoteVersion) {  
  482.         return GetVersionFromMeta(FilePath) == remoteVersion;  
  483.     }  
  484.     /// <summary>  
  485.     /// check file status  
  486.     /// </summary>  
  487.     /// <returns>0:normal    1:local ahead       -1:remote ahead      -2:local not exsit      -3:meta error</returns>  
  488.     public static int CheckFile(string URL, string RemoteVersion,bool EX = false) {  
  489.         string FilePath;  
  490.         if (!EX)  
  491.             FilePath = GetCacheURI(URL);  
  492.         else  
  493.             FilePath = GetCacheURIEX(URL);  
  494.         if (!File.Exists(FilePath)) {  
  495.             return -2;  
  496.         }  
  497.         string local = GetVersionFromMeta(FilePath);  
  498.         if (local == RemoteVersion) {  
  499.             return 0;  
  500.         }  
  501.         else {  
  502.             try {  
  503.                 int i_local = int.Parse(local);  
  504.                 int i_remote = int.Parse(RemoteVersion);  
  505.                 if (i_local<=i_remote) {  
  506.                     return -1;  
  507.                 }  
  508.                 else {  
  509.                     return 1;  
  510.                 }  
  511.             }  
  512.             catch {  
  513.                 return -3;  
  514.             }  
  515.         }  
  516.     }  
  517.     /// <summary>  
  518.     /// xor  
  519.     /// </summary>  
  520.     private static string XORStr(string p, string key) {  
  521.         byte[] ks = Encoding.UTF8.GetBytes(key);  
  522.         int kl = ks.Length;  
  523.         byte[] bs = Encoding.UTF8.GetBytes(p);  
  524.         for (int i = 0; i < bs.Length; i++) {  
  525.             bs[i] = (byte)(bs[i] ^ ks[i % kl]);  
  526.         }  
  527.         return Encoding.UTF8.GetString(bs);  
  528.     }  
  529.     private static void LogWWW(WWW www) {  
  530.         Debug.Log(www.url);  
  531.         if (www.error!=null)  
  532.         {  
  533.             Debug.Log(www.error);  
  534.         }  
  535.         var by = www.bytes;  
  536.         if (by.Length <= 10240) {//10k  
  537.             Debug.Log(www.text);  
  538.         }  
  539.         return;  
  540.         //follow code has some bug in ios,and it just want to write a log,so I haven`t cost time to fix it  
  541.         if (www==null || www.error == null){  
  542.              return;  
  543.         }  
  544.         StringBuilder sb = new StringBuilder();  
  545.         sb.AppendLine();  
  546.         sb.AppendLine(string.Format("-------{0}-------", System.DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")));  
  547.         sb.AppendLine("url:"+www.url);  
  548.         var rspHead = www.responseHeaders;  
  549.         sb.AppendLine("responseHeader:");  
  550.         foreach (var i in rspHead) {  
  551.             sb.AppendLine("  "+i.Key+""+i.Value);  
  552.         }  
  553.         sb.AppendLine("error:"+www.error);  
  554.         var b = www.bytes;  
  555.         if (b.Length<=10240) {//????????10k  
  556.             sb.AppendLine("text:"+www.text);  
  557.         }  
  558.         else {  
  559.             byte[] trim = new byte[40];  
  560.             Array.Copy(b,trim,trim.Length);  
  561.             sb.AppendLine(string.Format("text: ???????{0},???????????????,?40????:{1}",b.Length,Encoding.UTF8.GetString(trim)));  
  562.         }  
  563.         sb.AppendLine();  
  564.         File.AppendAllText(Application.persistentDataPath+"/WWWError.log", sb.ToString());  
  565.     }  
  566.     public static void ClearCache(string URL,bool EX) {  
  567.         string FilePath;  
  568.         if (!EX)  
  569.             FilePath = GetCacheURI(URL);  
  570.         else  
  571.             FilePath = GetCacheURIEX(URL);  
  572.         string metaPath = FilePath + ".yxMeta";  
  573.         if (File.Exists(FilePath)) {  
  574.             File.Delete(FilePath);  
  575.         }  
  576.         if (File.Exists(metaPath)) {  
  577.             File.Delete(metaPath);  
  578.         }  
  579.     }  
  580.     public static void ClearCache(string FilePath) {  
  581.         string metaPath = FilePath + ".yxMeta";  
  582.         if (File.Exists(FilePath)) {  
  583.             File.Delete(FilePath);  
  584.         }  
  585.         if (File.Exists(metaPath)) {  
  586.             File.Delete(metaPath);  
  587.         }  
  588.     }  
  589.     /// <summary>  
  590.     /// a wrapper of a WWW inst which has done  
  591.     /// </summary>  
  592.     public class WWWResult {  
  593.         WWW wwwInst;  
  594.         string overrideError = null;  
  595.         public WWWResult(WWW www) {  
  596.             wwwInst = www;  
  597.         }  
  598.         public void SetOverrideError(string error) {  
  599.             overrideError = error;  
  600.         }  
  601.         public AssetBundle assetBundle {  
  602.             get {  
  603.                 if (wwwInst!=null) {  
  604.                     return wwwInst.assetBundle;  
  605.                 }  
  606.                 else {  
  607.                     return null;  
  608.                 }  
  609.             }  
  610.         }  
  611.         public AudioClip audioClip {  
  612.             get {  
  613.                 if (wwwInst != null) {  
  614.                     return wwwInst.audioClip;  
  615.                 }  
  616.                 else {  
  617.                     return null;  
  618.                 }  
  619.             }  
  620.         }  
  621.         public byte[] bytes {  
  622.             get {  
  623.                 if (wwwInst != null) {  
  624.                     return wwwInst.bytes;  
  625.                 }  
  626.                 else {  
  627.                     return null;  
  628.                 }  
  629.             }  
  630.         }  
  631.         public string error {  
  632.             get {  
  633.                 if (wwwInst != null) {  
  634.                     if (!overrideError.IsNullOrEmpty()) {  
  635.                         return overrideError;  
  636.                     }  
  637.                     return wwwInst.error;  
  638.                 }  
  639.                 else {  
  640.                     return overrideError;  
  641.                 }  
  642.             }  
  643.         }  
  644.         public Dictionary<stringstring> responseHeaders {  
  645.             get {  
  646.                 if (wwwInst != null) {  
  647.                     return wwwInst.responseHeaders;  
  648.                 }  
  649.                 else {  
  650.                     return null;  
  651.                 }  
  652.             }  
  653.         }  
  654.         public int size {  
  655.             get {  
  656.                 if (wwwInst != null) {  
  657.                     return wwwInst.size;  
  658.                 }  
  659.                 else {  
  660.                     return -1;  
  661.                 }  
  662.             }  
  663.         }  
  664.         public string text {  
  665.             get {  
  666.                 if (wwwInst != null) {  
  667.                     if (!overrideError.IsNullOrEmpty()) {  
  668.                         return overrideError;  
  669.                     }  
  670.                     return wwwInst.text;  
  671.                 }  
  672.                 else {  
  673.                     return overrideError;  
  674.                 }  
  675.             }  
  676.         }  
  677.         public Texture2D texture {  
  678.             get {  
  679.                 if (wwwInst != null) {  
  680.                     return wwwInst.texture;  
  681.                 }  
  682.                 else {  
  683.                     return null;  
  684.                 }  
  685.             }  
  686.         }  
  687.         public Texture2D textureNonReadable {  
  688.             get {  
  689.                 if (wwwInst != null) {  
  690.                     return wwwInst.textureNonReadable;  
  691.                 }  
  692.                 else {  
  693.                     return null;  
  694.                 }  
  695.             }  
  696.         }  
  697.         public string url {  
  698.             get {  
  699.                 if (wwwInst != null) {  
  700.                     return wwwInst.url;  
  701.                 }  
  702.                 else {  
  703.                     return null;  
  704.                 }  
  705.             }  
  706.         }  
  707.         public AudioClip GetAudioClip(bool threeD) {  
  708.             if (wwwInst != null) {  
  709.                 return wwwInst.GetAudioClip(threeD);  
  710.             }  
  711.             else {  
  712.                 return null;  
  713.             }  
  714.         }  
  715.         public AudioClip GetAudioClip(bool threeD, bool stream) {  
  716.             if (wwwInst != null) {  
  717.                 return wwwInst.GetAudioClip(threeD,stream);  
  718.             }  
  719.             else {  
  720.                 return null;  
  721.             }  
  722.         }  
  723.         public AudioClip GetAudioClip(bool threeD, bool stream, AudioType audioType) {  
  724.             if (wwwInst != null) {  
  725.                 return wwwInst.GetAudioClip(threeD, stream, audioType);  
  726.             }  
  727.             else {  
  728.                 return null;  
  729.             }  
  730.         }  
  731.         public AudioClip GetAudioClipCompressed() {  
  732.             if (wwwInst != null) {  
  733.                 return wwwInst.GetAudioClipCompressed();  
  734.             }  
  735.             else {  
  736.                 return null;  
  737.             }  
  738.         }  
  739.         public AudioClip GetAudioClipCompressed(bool threeD) {  
  740.             if (wwwInst != null) {  
  741.                 return wwwInst.GetAudioClipCompressed(threeD);  
  742.             }  
  743.             else {  
  744.                 return null;  
  745.             }  
  746.         }  
  747.         public AudioClip GetAudioClipCompressed(bool threeD, AudioType audioType) {  
  748.             if (wwwInst != null) {  
  749.                 return wwwInst.GetAudioClipCompressed(threeD, audioType);  
  750.             }  
  751.             else {  
  752.                 return null;  
  753.             }  
  754.         }  
  755.         public void LoadImageIntoTexture(Texture2D tex) {  
  756.             if (wwwInst != null) {  
  757.                 wwwInst.LoadImageIntoTexture(tex);  
  758.             }  
  759.             else {  
  760.                 return;  
  761.             }  
  762.         }  
  763.     }  
  764. }  

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

[csharp]  view plain  copy
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. using System;  
  5. using System.Reflection;  
  6. /// <summary>  
  7. /// Э?????д???  
  8. /// </summary>  
  9. public class CoroutineWrapper : MonoBehaviour {  
  10.     #region ????  
  11.     static CoroutineWrapper inst;  
  12.     private readonly static object mutex = new object();  
  13.     public static CoroutineWrapper Inst {  
  14.         get {  
  15.             if (inst == null) {  
  16.                 var obj = new GameObject("CoroutineWrapper");  
  17.                 DontDestroyOnLoad(obj);  
  18.                 inst = obj.AddComponent<CoroutineWrapper>();  
  19.                 inst.Init();  
  20.             }  
  21.             return inst;  
  22.         }  
  23.     }  
  24.     void Init() {  
  25.         inst = this;  
  26.     }  
  27.     #endregion  
  28.     /// <summary>  
  29.     /// ????????????  
  30.     /// </summary>  
  31.     /// <param name="frames"></param>  
  32.     /// <param name="ev"></param>  
  33.     /// <returns></returns>  
  34.     public IEnumerator ExeDelay(int frames,Action ev) {  
  35.         for (int i = 0; i < frames;i++ ) {  
  36.             yield return new WaitForEndOfFrame();  
  37.         }  
  38.         ev();  
  39.     }  
  40.     /// <summary>  
  41.     /// ????????????  
  42.     /// </summary>  
  43.     /// <param name="sec"></param>  
  44.     /// <param name="ev"></param>  
  45.     /// <returns></returns>  
  46.     public IEnumerator ExeDelayS(float sec, Action ev) {  
  47.         yield return new WaitForSeconds(sec);  
  48.         ev();;  
  49.     }  
  50.     /// <summary>  
  51.     /// ????????????  
  52.     /// </summary>  
  53.     /// <param name="sec"></param>  
  54.     /// <param name="ev"></param>  
  55.     public static void EXES(float sec, Action ev) {  
  56.         inst.StartCoroutine(inst.ExeDelayS(sec,ev));  
  57.     }  
  58.     /// <summary>  
  59.     /// ????????????  
  60.     /// </summary>  
  61.     /// <param name="frames"></param>  
  62.     /// <param name="ev"></param>  
  63.     public static void EXEF(int frames, Action ev) {  
  64.         inst.StartCoroutine(inst.ExeDelay(frames, ev));  
  65.     }  
  66.     /// <summary>  
  67.     /// ?????????Э??  
  68.     /// </summary>  
  69.     /// <param name="ien">Э?????</param>  
  70.     public static void EXEE(Func<IEnumerator> ien) {  
  71.         inst.StartCoroutine(ien());  
  72.     }  
  73.     /// <summary>  
  74.     ///  
  75.     /// </summary>  
  76.     /// <param name="ien">Э?????</param>  
  77.     /// <param name="p">??????</param>  
  78.     public static void EXEE(Func<object[],IEnumerator> ien,params object[] p) {  
  79.         inst.StartCoroutine(ien(p));  
  80.     }  
  81.     /// <summary>  
  82.     /// call fun with any type args,function must be public  
  83.     /// </summary>  
  84.     /// <param name="t"></param>  
  85.     /// <param name="FuncName"></param>  
  86.     /// <param name="inst"></param>  
  87.     /// <param name="p"></param>  
  88.     public static void ReflectCallCoroutine(Type t, string FuncName,object inst, params object[] p) {  
  89.         Type[] pt = null;  
  90.         if (p!=null) {  
  91.             pt = new Type[p.Length];  
  92.             for (int i = 0; i < pt.Length; i++) {  
  93.                 pt[i] = p[i].GetType();  
  94.             }  
  95.         }  
  96.         MethodInfo method;  
  97.         if (pt!=null) {  
  98.             method = t.GetMethod(FuncName,pt);  
  99.         } else {  
  100.             method = t.GetMethod(FuncName);  
  101.         }  
  102.         if (method == null) {  
  103.             Debug.LogFormat("can`t find method {0} with give params",FuncName);  
  104.             return;  
  105.         }  
  106.         var u3dCoroutineCaller = inst.GetType().GetMethod("StartCoroutine"new Type[] { typeof(IEnumerator) });  
  107.         if (u3dCoroutineCaller == null) {  
  108.             Debug.Log("can`t find u3d coroutine caller");  
  109.             return;  
  110.         }  
  111.         u3dCoroutineCaller.Invoke(inst, new object[]{method.Invoke(inst, p)});  
  112.     }  
  113.     /// <summary>  
  114.     /// this action will be called per frame  
  115.     /// </summary>  
  116.     public event Action OnPerFrame;  
  117.     void Update() {  
  118.         if (OnPerFrame != null)  
  119.             OnPerFrame();  
  120.     }  
  121. }  

好了,举个栗子:

先初始化一下工具:

[csharp]  view plain  copy
  1. void Awake() {  
  2.     var t = CoroutineWrapper.Inst;  
  3. }  
再开始你的http访问,例如下面这个,是提交评论

[csharp]  view plain  copy
  1. public WWWEX CommentProjImpl(string uid, string comment, Action<WWWEX.WWWResult> callback) {  
  2.         string url = "xxx";  
  3.         WWWEX wex = new WWWEX();  
  4.         WWWForm form = new WWWForm();  
  5.         form.AddField("uniqid",uid);  
  6.         form.AddField("content", comment);  
  7.         wex.www(url, form.data, MakeHeader(), callback);//MakeHeader是一个生成一些请求头字段的方法,生成的一个Dictionary<string, string>,可以不管  
  8.         return wex;  
  9.     }  
然后,这个函数就返回了一个WWWEX的实例,要获取进度之类的就是可以通过这个实例的成员去访问。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值