/// <summary> /// 加载各个平台的总记录的ab /// </summary> /// <returns></returns> IEnumerator WWWLoadMainAssets() { string url = GetMainABPath(); VersionAssetData vad = mNameMD5Dic[mMainABPath]; yield return(null); WWW mainWWW = new WWW(url); yield return(mainWWW); if (mainWWW.error != null) { Debug.LogError("WWWLoadMainAssets Error:" + url); } else { AssetBundle ab = mainWWW.assetBundle; mMainManifest = (AssetBundleManifest)ab.LoadAsset("AssetBundleManifest"); ab.Unload(false); //开始加载任务队列 //yield return StartCoroutine(Run()); if (OnAssetsPrepareComplete != null) { OnAssetsPrepareComplete(); OnAssetsPrepareComplete = null; } else { Debug.LogError("OnAssetsPrepareComplete is null"); } } }
/// <summary> /// 加载各个平台的总记录的ab的 manifest信息 这是加载ab的前提 /// </summary> /// <returns></returns> IEnumerator WWWLoadMainAssets() { VersionAssetData vad = mNameMD5Dic["Manifest"]; string url = StringBuilder(GetPlantFormat(), "/", vad.md5); //只提供了测试加载,android不能通过File加载需要通过www方式 #if UNITY_IPHONE || UNITY_STANDALONE_WIN || UNITY_EDITOR if (!File.Exists(url)) { Debug.LogError("Manifest file not exist:" + url); } else { var fs = File.OpenRead(url); int fsLen = (int)fs.Length; byte[] heByte = new byte[fsLen]; //int r = fs.Read(heByte, 0, heByte.Length); fs.Read(heByte, 0, heByte.Length); string text = System.Text.Encoding.UTF8.GetString(heByte); mMainManifest = IAssetBundleManifest.DeSerializate(text); fs.Dispose(); } #endif yield return(null); LoadAssets("prefab/cube", (o, obj) => { Debug.Log(" 加载资源成功!!!"); GameObject.Instantiate(o); }); }
/// <summary> /// 下载资源包 /// </summary> /// <param name="data"></param> /// <returns></returns> private IEnumerator DownloadAssetBundle(VersionAssetData data) { string loadPath = GetAssetServerPath(data.path, data.md5); WWW www = new WWW(ComTool.FormatTickUrl(loadPath)); yield return(www); if (www.error != null) { Debug.LogError("DownloadAssetBundle Error:" + data.name); SendErrorCode(404); } else { if (CheckDataValid(data, www.bytes)) { WriteAssetOnLocal(data, www.bytes); } else { Debug.LogError("CheckDataValid false:" + data.name); } } www.Dispose(); }
IEnumerator SetMD5AssetsList() { mNameMD5Dic = new Dictionary <string, VersionAssetData>(); string localPath = mLocalResRootPath + "/" + RVL; #if UNITY_STANDALONE_WIN || UNITY_EDITOR localPath = mLocalResRootPath + "/" + RVL; #elif UNITY_ANDROID localPath = mLocalResRootPath + "/" + RVL; #elif UNITY_IPHONE localPath = mLocalResRootPath + "/" + RVL; #endif //WWW localWWW = new WWW("File://" + localPath); if (!File.Exists(localPath)) { Debug.LogError("SetMD5AssetsList file not exist:" + localPath); } else { using (FileStream fs = new FileStream(localPath, FileMode.Open)) { int fsLen = (int)fs.Length; byte[] heByte = new byte[fsLen]; //int r = fs.Read(heByte, 0, heByte.Length); fs.Read(heByte, 0, heByte.Length); string text = System.Text.Encoding.UTF8.GetString(heByte); XmlDocument document = new XmlDocument(); document.LoadXml(text); XmlNode root = document.SelectSingleNode("root"); foreach (XmlNode _node in root.ChildNodes) { XmlElement node = _node as XmlElement; if (node == null) { continue; } if (node.Name.Equals("asset")) { VersionAssetData loadAsset = new VersionAssetData(); loadAsset.name = node.GetAttribute("name"); loadAsset.md5 = node.GetAttribute("md5"); loadAsset.size = System.Convert.ToInt32(node.GetAttribute("size")); loadAsset.path = node.GetAttribute("path"); if (!mNameMD5Dic.ContainsKey(loadAsset.name)) { mNameMD5Dic.Add(loadAsset.name, loadAsset); } } } Debug.Log("mNameMD5Dic Count " + mNameMD5Dic.Count); yield return(StartCoroutine(WWWLoadMainAssets())); } } }
/// <summary> /// 检测资源完整合理性 /// </summary> /// <param name="data"></param> /// <param name="bytes"></param> /// <returns></returns> private bool CheckDataValid(VersionAssetData data, byte[] bytes) { string md5 = GetMd5(bytes); if (data.md5 != md5) { SendErrorCode(401); } return(true); }
/// <summary> /// 更新本地资源版本列表 /// </summary> /// <param name="data"></param> private void UpdateLocalRVL(VersionAssetData data) { if (m_LocalRVLDic == null) { m_LocalRVLDic = new Dictionary <string, VersionAssetData>(); } string name = GetAssetName(data.name); if (m_LocalRVLDic.ContainsKey(name)) { m_LocalRVLDic[name] = data; } else { m_LocalRVLDic.Add(name, data); } WriteLocalRVL(); }
/// <summary> /// 写入资源到本地 /// </summary> /// <param name="data"></param> /// <param name="bytes"></param> private void WriteAssetOnLocal(VersionAssetData data, byte[] bytes) { //删除之前存在的旧md5码资源 if (m_LocalRVLDic != null) { if (m_LocalRVLDic.ContainsKey(data.name)) { string oldPath = m_LocalResRootPath + "/" + m_LocalRVLDic[data.name].md5; if (File.Exists(oldPath)) { File.Delete(oldPath); } } } string localPath = GetAssetLocalPath(data.path, data.md5); FileInfo t = new FileInfo(localPath); if (t.Exists) { DeleteAsset(localPath); } try { if (!t.Exists) { Directory.CreateDirectory(t.DirectoryName); } File.WriteAllBytes(localPath, bytes); } catch (System.Exception ex) { Debug.LogError(ex.ToString()); SendErrorCode(201); } UpdateLocalRVL(data); }
/// <summary> /// 获取主ab资源地址 /// </summary> /// <returns></returns> private string GetMainABPath() { string url = ""; VersionAssetData vad = mNameMD5Dic[mMainABPath]; if (File.Exists(mLocalResRootPath + "/" + vad.md5)) { #if UNITY_STANDALONE_WIN || UNITY_EDITOR url = "File://" + mLocalResRootPath + "/" + vad.md5; #elif UNITY_ANDROID url = "File://" + mLocalResRootPath + "/" + vad.md5; #elif UNITY_IPHONE url = "File://" + mLocalResRootPath + "/" + vad.md5; #endif return(url); } else { url = mStreamResRootPath + "/" + vad.md5; return(url); } }
/// <summary> /// 解析资源版本列表 /// </summary> /// <param name="xml"></param> /// <returns></returns> private Dictionary <string, VersionAssetData> ParserResVersionList(string xml, ref string version) { XmlDocument document = new XmlDocument(); document.LoadXml(xml); Dictionary <string, VersionAssetData> resVersionList = new Dictionary <string, VersionAssetData>(); XmlNode root = document.SelectSingleNode("root"); XmlElement rootNode = root as XmlElement; if (rootNode != null) { version = rootNode.GetAttribute("version"); } foreach (XmlNode _node in root.ChildNodes) { XmlElement node = _node as XmlElement; if (node == null) { continue; } if (node.Name == "asset") { VersionAssetData loadAsset = new VersionAssetData(); loadAsset.name = node.GetAttribute("name"); loadAsset.md5 = node.GetAttribute("md5"); loadAsset.size = System.Convert.ToInt32(node.GetAttribute("size")); loadAsset.path = node.GetAttribute("path"); string name = GetAssetName(loadAsset.name); if (!resVersionList.ContainsKey(name)) { resVersionList.Add(name, loadAsset); } } } return(resVersionList); }
/// <summary> /// 真正加载的地方 /// </summary> /// <param name="path"></param> /// <param name="dp"></param> /// <param name="cb"></param> /// <param name="obj"></param> /// <returns></returns> void SynLoadAssets(string path, bool dp, object obj, LoadComplete cb) { if (mNameMD5Dic.ContainsKey(path)) { VersionAssetData vad = mNameMD5Dic[path]; string url = GetAssetsFilePath(vad.path, vad.md5); AssetBundle ab = null; if (!dp) { // 作为主资源加载的 AssetsBundleData abd = null; if (mAssetsABDic.ContainsKey(path))//已经被加载过 计数器自增 { abd = mAssetsABDic[path]; abd.depIndex += 1; ab = abd.ab; } else { // 新加载的 ab = AssetBundle.LoadFromFile(url); abd = new AssetsBundleData(); abd.name = path; abd.depIndex = 1; abd.ab = ab; mAssetsABDic.Add(path, abd); } string[] dpAbs = mMainManifest.GetAllDependencies(path); //取这个资源的所有依赖资源 #region if (dpAbs != null && dpAbs.Length == 0) //没有依赖 获取资源 { UnityEngine.Object o = GetObj(ab, path); if (cb != null) { cb.Invoke(o, obj); } } #endregion #region else { //存在依赖资源 #region for (int i = 0; i < dpAbs.Length; i++) { if (mAssetsABDic.ContainsKey(dpAbs[i])) { // 依赖计数器中已经存在了 计数器+1 abd = mAssetsABDic[dpAbs[i]]; abd.depIndex += 1; } else { SynLoadAssets(dpAbs[i], true, obj, cb); } } //依赖都加载完毕了 再看主资源 UnityEngine.Object o = GetObj(ab, path); if (cb != null) { cb.Invoke(o, obj); } #endregion } } #endregion else { // 作为被依赖资源下载 AssetsBundleData abd = null; if (mAssetsABDic.ContainsKey(path)) { abd = mAssetsABDic[path]; abd.depIndex += 1; } else//被依赖的 缓存 { ab = AssetBundle.LoadFromFile(url); abd = new AssetsBundleData(); abd.name = path; abd.depIndex = 1; abd.ab = ab; mAssetsABDic.Add(path, abd); } } } else { Debug.LogError("cannot find:" + path); } }
/// <summary> /// 取资源的md5信息 /// </summary> /// <returns></returns> IEnumerator SetMD5AssetsList() { mNameMD5Dic = new Dictionary <string, VersionAssetData>(); string localPath = mLocalResRootPath + "/" + RVL; #if UNITY_STANDALONE_WIN || UNITY_EDITOR localPath = mLocalResRootPath + "/" + RVL; #elif UNITY_ANDROID localPath = mLocalResRootPath + "/" + RVL; #elif UNITY_IPHONE localPath = mLocalResRootPath + "/" + RVL; #endif yield return(null); WWW localWWW = new WWW("File://" + localPath); yield return(localWWW); if (localWWW.error != null) { if (mIndex > 5) { Debug.LogError("can not find:" + localPath); } else { mIndex += 1; Debug.LogError("test www load:" + mIndex); yield return(new WaitForSeconds(0.5f)); StartCoroutine(SetMD5AssetsList()); } } else { mIndex = 0; XmlDocument document = new XmlDocument(); document.LoadXml(localWWW.text); XmlNode root = document.SelectSingleNode("root"); foreach (XmlNode _node in root.ChildNodes) { XmlElement node = _node as XmlElement; if (node == null) { continue; } if (node.Name == "asset") { VersionAssetData loadAsset = new VersionAssetData(); loadAsset.name = node.GetAttribute("name"); loadAsset.md5 = node.GetAttribute("md5"); loadAsset.size = System.Convert.ToInt32(node.GetAttribute("size")); loadAsset.path = node.GetAttribute("path"); if (!mNameMD5Dic.ContainsKey(loadAsset.name)) { mNameMD5Dic.Add(loadAsset.name, loadAsset); } } } yield return(StartCoroutine(WWWLoadMainAssets())); } }
/// <summary> /// 加载资源包 /// </summary> /// <param name="dpName"></param> /// <param name="mainName">主资源名称</param> /// <returns></returns> IEnumerator WWWLoadAssets(string name, bool dp) { if (mAssetsABDic.ContainsKey(name)) { AssetsBundleData abd = mAssetsABDic[name]; abd.depIndex += 1; } else { if (mNameMD5Dic.ContainsKey(name)) { VersionAssetData vad = mNameMD5Dic[name]; /* * string url = GetAssetsWWWPath(vad.path, vad.md5); * WWW abWWW = new WWW(url); * yield return abWWW; */ string url = GetAssetsFilePath(vad.path, vad.md5); byte[] bytes = ComTool.ReadFile(url); if (bytes != null) { AssetBundle ab = null; if (!dp) { //作为主资源加载的 ab = AssetBundle.LoadFromMemory(bytes); string[] dpAbs = mMainManifest.GetAllDependencies(name); //取这个资源的所有依赖资源 if (dpAbs.Length == 0) //没有依赖 { #region AssetsBundleData abd = new AssetsBundleData(); abd.name = name; abd.depIndex = 1; abd.ab = ab; mAssetsABDic.Add(name, abd); #endregion } else { //存在依赖资源 #region for (int i = 0; i < dpAbs.Length; i++) { if (mAssetsABDic.ContainsKey(dpAbs[i])) { //依赖计数器中已经存在了 计数器+1 AssetsBundleData abd = mAssetsABDic[dpAbs[i]]; abd.depIndex += 1; } else { yield return(StartCoroutine(WWWLoadAssets(dpAbs[i], true))); } } #endregion //依赖都加载完毕了 再看主资源 #region if (!mAssetsABDic.ContainsKey(name)) { AssetsBundleData abd = new AssetsBundleData(); abd.name = name; abd.depIndex = 1; abd.ab = ab; mAssetsABDic.Add(name, abd); } else { AssetsBundleData abd = mAssetsABDic[name]; abd.depIndex += 1; } #endregion } } else {//作为被依赖资源下载 AssetsBundleData abd = null; if (mAssetsABDic.ContainsKey(name)) { abd = mAssetsABDic[name]; abd.depIndex += 1; } else { ab = AssetBundle.LoadFromMemory(bytes); abd = new AssetsBundleData(); abd.name = name; abd.depIndex = 1; abd.ab = ab; mAssetsABDic.Add(name, abd); } } if (!dp) { //资源包加载完成计数+1 mLoadedNum += 1; //Debug.LogError("module loaded num:" + mLoadedNum); } } else { Debug.LogError("cannot find:" + url); } } } }