AssetBundle打包写入MD5待更新文件

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using System.Collections.Generic;
using LitJson;public class EditorCreateBundle : Editor
{public static string m_BundleDirectory = Application.dataPath + "/AssetBundle/";[MenuItem("Tools/Bundle/IOS打Bundle")]static void BuildReleaseIOSBundle(){BuildBundleTest(BuildTarget.iOS);}[MenuItem("Tools/Bundle/Android打Bundle")]static void BuildReleaseAndroidBundle(){BuildBundleTest(BuildTarget.Android);}[MenuItem("Tools/Bundle/Windows64打Bundle")]static void BuildReleaseWindowsBundle(){BuildBundleTest(BuildTarget.StandaloneWindows64);}static void BuildBundleTest(BuildTarget target){Caching.ClearCache();string[] filePaths = Directory.GetDirectories(m_BundleDirectory, "*.*", SearchOption.TopDirectoryOnly);string path = GetTempPath(target);DeleteTempBundles(target);SetAssetBundleName(filePaths);BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.ChunkBasedCompression, target);CreateBundleVersionNumber(path, target);AssetDatabase.Refresh();}private static Dictionary<string, string> m_BundleMD5Map = new Dictionary<string, string>();/// <summary>/// 删除目标文件夹下的所有文件/// </summary>/// <param name="target"></param>static void DeleteTempBundles(BuildTarget target){string[] bundleFiles = GetAllFilesFromBundleDirectory(target);foreach (string s in bundleFiles){File.Delete(s);}}static string[] GetAllFilesFromBundleDirectory(BuildTarget target){string path = GetTempPath(target);if (!Directory.Exists(path))Directory.CreateDirectory(path);string[] bundleFiles = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);return bundleFiles;}static void SetAssetBundleName(string[] topDirectories){foreach (string path in topDirectories){string[] childPaths = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);string childPathName, extension, directoryName;foreach (string childPath in childPaths){extension = Path.GetExtension(childPath);if (extension != ".meta" && extension != ".DS_Store"){childPathName = Path.GetFileNameWithoutExtension(childPath);directoryName = Path.GetDirectoryName(childPath).Replace("\\", "/");AssetImporter temp = AssetImporter.GetAtPath(childPath.Replace(Application.dataPath, "Assets"));temp.assetBundleName = null;if (directoryName.ToLower().IndexOf("sprite") >= 0){AssetImporter ai = AssetImporter.GetAtPath(directoryName.Replace(Application.dataPath, "Assets"));ai.assetBundleName = directoryName.Replace(m_BundleDirectory, "");}elsetemp.assetBundleName = directoryName.Replace(m_BundleDirectory, "") + "/" + childPathName;}}}}/// <summary>获取文件的md5校验码</summary>static string GetMD5HashFromFile(string fileName){if (File.Exists(fileName)){FileStream file = new FileStream(fileName, FileMode.Open);MD5 md5 = new MD5CryptoServiceProvider();byte[] retVal = md5.ComputeHash(file);file.Close();StringBuilder sb = new StringBuilder();for (int i = 0; i < retVal.Length; i++)sb.Append(retVal[i].ToString("x2"));return sb.ToString();}return null;}static void CreateBundleVersionNumber(string bundlePath, BuildTarget target){JsonData serverJson = new JsonData();string[] contents = Directory.GetFiles(bundlePath, "*.*", SearchOption.AllDirectories);string extension;string fileName = "";string fileMD5 = "";long allLength = 0;int fileLen;m_BundleMD5Map.Clear();for (int i = 0; i < contents.Length; i++){fileName = contents[i].Replace(GetTempPath(target), "").Replace("\\", "/");extension = Path.GetExtension(contents[i]);if (extension != ".meta"){fileMD5 = GetMD5HashFromFile(contents[i]);fileLen = File.ReadAllBytes(contents[i]).Length;allLength += fileLen;m_BundleMD5Map.Add(fileName, fileMD5 + "+" + fileLen);}}JsonData files = new JsonData();foreach (KeyValuePair<string, string> kv in m_BundleMD5Map){JsonData jd = new JsonData();jd["file"] = kv.Key;string[] nAndL = kv.Value.Split('+');jd["md5"] = nAndL[0];jd["fileLength"] = nAndL[1];files.Add(jd);}serverJson["length"] = allLength;serverJson["files"] = files;File.WriteAllText(GetTempPath(target) + "Bundle.txt", serverJson.ToJson());m_BundleMD5Map.Clear();//MiscUtils.CopyDirectory(Application.streamingAssetsPath + "/AssetBundle", Application.dataPath.Replace("Assets", ""), "*.*", true);//Directory.Delete(Application.streamingAssetsPath + "/AssetBundle", true);}static string GetTempPath(BuildTarget target){return Application.streamingAssetsPath + "/";}
}

服务端比对版本更新

  /// <summary>/// 版本更新/// </summary>/// <returns></returns>IEnumerator VersionUpdate(){WWW www = new WWW(ConstantUtils.HttpDownLoadUrl + "Bundle.txt");yield return www;if (www.isDone && string.IsNullOrEmpty(www.error)){List<BundleInfo> bims = new List<BundleInfo>();JsonData data = JsonMapper.ToObject(www.text);string md5, file, path;int lenth;for (int i = 0; i < data["files"].Count; i++){JsonData jd = data["files"][i];file = jd.TryGetstring("file");path = ConstantUtils.PathUrl(file);md5 = GetMD5HashFromFile(path);if (string.IsNullOrEmpty(md5) || md5 != jd.TryGetstring("md5")){bims.Add(new BundleInfo(){Url = ConstantUtils.HttpDownLoadUrl +file,Path = path});lenth = int.Parse(jd.TryGetstring("fileLength"));allfilesLength += lenth;}}if (bims.Count > 0){GameObject.Find("Canvas").transform.Find("LoadPage").gameObject.SetActive(true);StartCoroutine(DownLoadBundleFiles(bims, (progress) => {OpenLodingShow("自动更新中...", progress, allfilesLength);}, (isfinish) => {if (isfinish)StartCoroutine(VersionUpdateFinish());else{LoadingPage.Instance.GetMyEvent.Invoke("部分文件更新失败,正在准备重试...");StartCoroutine(VersionUpdate());}}));}else{//Debug.Log(ConstantUtils.DataPath("common/luascript/XLuaScript.lua.txt", _pathinfo.streamingAssetsPath));StartCoroutine(VersionUpdateFinish());}}}/// <summary>获取文件的md5校验码</summary>public static string GetMD5HashFromFile(string fileName){if (File.Exists(fileName)){FileStream file = new FileStream(fileName, FileMode.Open);MD5 md5 = new MD5CryptoServiceProvider();byte[] retVal = md5.ComputeHash(file);file.Close();StringBuilder sb = new StringBuilder();for (int i = 0; i < retVal.Length; i++)sb.Append(retVal[i].ToString("x2"));return sb.ToString();}return null;}public LuaEnv LuaEnvt { get; private set; }Action StartLua;Action UpdateLua;Action DestoryLua;IEnumerator VersionUpdateFinish(){// LoadingNode.instance.Close();GameObject.Find("Canvas").transform.Find("LoadPage").gameObject.SetActive(false);
//登录验证...执行lua文件LuaEnvt = new LuaEnv();TextAsset texts = Singleton<UIManager>.singleton.GetBundleFile<TextAsset>("Lua/FirstLua.lua", "FirstLua.lua");LuaEnvt.DoString(texts.text);StartLua = LuaEnvt.Global.Get<Action>("start");UpdateLua = LuaEnvt.Global.Get<Action>("update");DestoryLua = LuaEnvt.Global.Get<Action>("ondestroy");yield return new WaitForEndOfFrame();if (StartLua != null)StartLua();}/// <summary>/// 路径比对/// </summary>/// <param name="infos"></param>/// <param name="LoopCallBack"></param>/// <param name="CallBack"></param>/// <returns></returns>public IEnumerator DownLoadBundleFiles(List<BundleInfo> infos, Action<float> LoopCallBack = null, Action<bool> CallBack = null){int num = 0;string dir;for (int i = 0; i < infos.Count; i++){BundleInfo info = infos[i];WWW www = new WWW(info.Url);yield return www;if (www.isDone && string.IsNullOrEmpty(www.error)){try{string filepath = info.Path;dir = Path.GetDirectoryName(filepath);if (!Directory.Exists(dir))Directory.CreateDirectory(dir);File.WriteAllBytes(filepath, www.bytes);num++;if (LoopCallBack != null)LoopCallBack.Invoke((float)num / infos.Count);}catch (Exception e){Debug.Log("下载失败pp");}}else{Debug.Log("没有进去");}}if (CallBack != null)CallBack.Invoke(num == infos.Count);}/// <summary>/// 记录信息/// </summary>public struct BundleInfo{public string Path { get; set; }public string Url { get; set; }public override bool Equals(object obj){return obj is BundleInfo && Url == ((BundleInfo)obj).Url;}public override int GetHashCode(){return Url.GetHashCode();}}/// <summary>/// loadpage展示/// </summary>/// <param name="text"></param>/// <param name="progress"></param>/// <param name="filealllength"></param>public static void OpenLodingShow(string text = null, float progress = 0, long filealllength = 0){string allLength = ConstantUtils.GetMillionFromByte(filealllength).ToString("F2");string currlength = ConstantUtils.GetMillionFromByte((long)(filealllength * progress)).ToString("F2");LoadingPage.Instance.PrograssText.text = "<color=#8CF976FF>" + currlength + "MB</color>/<color=#FEE646FF>" + allLength + "MB</color>";LoadingPage.Instance.imagePrograss.DOFillAmount(progress, 0.5f);if (!string.IsNullOrEmpty(text))LoadingPage.Instance.LodingDes.text = text;elseLoadingPage.Instance.LodingDes.text = text;}void Update() {if (UpdateLua != null){UpdateLua.Invoke();}if (LuaEnvt != null)LuaEnvt.Tick();}private void OnDestroy(){if (DestoryLua != null)DestoryLua();UpdateLua = null;DestoryLua = null;StartLua = null;// LuaEnvt.Dispose();}

unity3d Md5打包与版本更新相关推荐

  1. Unity3D 预设打包的注意事项

    Unity3D 预设打包的注意事项 在平时的开发中,把预设打包成 assetbundle 文件是非常普遍的做法,但是我们不能随便把预设打包成 assetbundle 就算完事,我们应该先清楚把预设打包 ...

  2. unity3d安卓打包教程

    unity3d安卓打包教程

  3. [Unity3d]制作打包并载入AssetBundle

    通常在游戏执行过程中,并不希望一次将全部的资源都载入.而是在资源被使用的时候载入,以免占用过多的存储空间.所以我们可能会尽量规划好不同功能的场景,在需要的时候才载入场景并释放掉前个场景中不需要的资源. ...

  4. unity3d 资源打包加密

    资源打包脚本,放到Assets\Editor 文件夹下 using UnityEngine; using System.Collections; using UnityEditor; using Sy ...

  5. 【Unity3D日常开发】Unity3D中打包WEBGL后读取本地文件数据

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  6. Unity3D 自动打包整个项目(以AssetBundle实现)

    需求: 在移动开发中,手动控制资源的加载.释放和热更新,是很有必要的. 而Unity通过AssetBundle可以实现该需求,但是如果项目资源多起来的话一个个手动打包成AssetBundle则很麻烦. ...

  7. [Unity3d][NGUI]打包NGUI预制件成Assetbundle 两种思路.

    http://www.58player.com/blog-2537-85030.html 接上文,项目中因为需要UI热更新,所以我使用了AssetBundle这个解决方案.               ...

  8. 一次Unity3D IL2CPP 打包错误

    目录 一.错误描述 二.问题分析 三.解决方法 四.效果验证 五.后记 一.错误描述 采用IL2CPP生成的时候,出现了4个错误: (1)Building Library\Bee\artifacts\ ...

  9. Android:AS与Unity3D之间打包的各种坑及解决方案

    作者:DrkCore (http://blog.csdn.net/DrkCore)  原文链接:(http://blog.csdn.net/drkcore/article/details/520793 ...

  10. 关于Unity3D开发三星Gear VR的初步尝试(一):已实现打包到手机显示

    这两天老师催我把前段时间买的三星GearVR在Unity3D尝试打包,不然就白买了,到现在已经成功实现了打包.我把记录贴下来,以免未来可能用. 1.需要的硬件:三星GearVR.三星s8+(其他的几代 ...

最新文章

  1. 华岩资本--微生物领域项目投递通道
  2. Ubuntu 安装软件方法
  3. 【数字信号处理】相关系数 ( 相关系数概念解析 | 信号能量常数 | 共轭序列 | 序列在相同时刻的相关性 )
  4. 深度学习框架不能“包治百病”,开发者如何选出最适合自己的?
  5. php 微信支付md5签名,微信支付回调验证签名处理
  6. 用WebService实现调用新浪的天气预报功能
  7. (二十六)java版spring cloud+spring boot 社交电子商务平台-Eureka介绍
  8. python3.7安装wxPython后导入wx报错
  9. 新疆师范大学计算机研究生值得读吗,研究生还值得读吗
  10. 快速开发:普元EOS平台简介
  11. FIT2CLOUD飞致云被权威研究机构评选为中国混合云管理软件领导者
  12. python爬虫实例评论_python爬取微博评论的实例讲解
  13. 吴恩达机器学习笔记目录
  14. 【转载】Oracle之同义词(SYNONYM)
  15. C语言求等腰梯形面积,几道C语言的题目!
  16. 安卓TV开发(四) 实现主流智能TV视频播放器UI
  17. 地理信息系统GIS小结
  18. html5图片中加入文字,HTML肿么在图片上添加文字,也就是图片作为背景,代码和图像显示如下...
  19. 2018年人均寿命是多少_那是2018年
  20. 三支决策(从粗糙集说起)

热门文章

  1. 板簧的弹性系数如何计算_一种板簧总成的刚度计算方法、系统及可读存储介质与流程...
  2. [写轮眼]QQ服务调校
  3. 爬虫 + 数据分析 - 7 CrawlSpider(全站爬取), 分布式, 增量式爬虫
  4. 西门子1200PLC(入门)2
  5. hprose-php教程,Swoole学习笔记(六):Hprose入门
  6. 隐马尔可夫python_隐马尔可夫模型原理和python实现
  7. 配置 Linux 阿里源
  8. 最小巧最简单最安全的KMS模拟器vlmcsd,最新支持Win10 server2016和Office2016!
  9. 暗时间 pdf_时间管理最全的一篇:理论+实践+电子书
  10. 编译jemalloc以及报错解决