List <string> GetLocalWithDefaultDifference(CustomAssetBundleManifest localManifest, CustomAssetBundleManifest defaultManifest) { List <string> difference = new List <string>(); List <string> loadFromLocal = CustomAssetBundleManifest.GetDifference(localManifest, defaultManifest); foreach (var item in loadFromLocal) { difference.Add(item); } return(difference); }
public static void GenerateAssetBundle(BuildTarget target, bool isCompress) { // Load manifest txt or assetbundle string manifestPathName = Path.Combine(AssetBundleConfig.AssetBundlesRoot, new DirectoryInfo(AssetBundleConfig.AssetBundlesRoot).Name).Replace("\\", "/").ToLower(); AssetBundle bundle = AssetBundle.LoadFromFile(manifestPathName); AssetBundleManifest u3dManifest = bundle.LoadAsset("AssetBundleManifest") as AssetBundleManifest; List <AssetBundleInfo> assetBundles = new List <AssetBundleInfo>(); if (u3dManifest != null) { foreach (var item in u3dManifest.GetAllAssetBundles()) { string itemPath = Path.Combine(AssetBundleConfig.AssetBundlesRoot, item).Replace("\\", "/").ToLower(); AssetBundleInfo info = new AssetBundleInfo(); info.relativePath = item; info.dependencies = u3dManifest.GetAllDependencies(item); info.MD5 = GetMD5HashFromFile(itemPath); AssetBundle subAssetBundle = AssetBundle.LoadFromFile(itemPath); if (subAssetBundle == null) { throw new System.Exception(item + "is not existed! CreateManifest()"); } info.allAssetsName = subAssetBundle.GetAllAssetNames(); SetAssetNames(info.allAssetsName); // This would be used as key to query assetbundle file. assetBundles.Add(info); subAssetBundle.Unload(true); } } bundle.Unload(true); CheckRepeatedAssetName(assetBundles); //create my manifest string tempPath = "Assets/assetsmanifest.json"; CustomAssetBundleManifest.JsonSerialize(assetBundles, tempPath, isCompress); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); //AssetImporter.GetAtPath(tempPath).assetBundleName = AssetBundleConfig.ManifestRelativePath; AssetBundleBuild[] buildManifests = new AssetBundleBuild[1]; buildManifests[0].assetNames = new string[] { tempPath }; buildManifests[0].assetBundleName = AssetBundleConfig.ManifestRelativePath; BuildPipeline.BuildAssetBundles(AssetBundleConfig.AssetBundlesRoot, buildManifests, BuildAssetBundleOptions.UncompressedAssetBundle, target); #if !LEAVE_CFG_FILE FileUtil.DeleteFileOrDirectory(AssetBundleConfig.DstDir + "AssetBundle"); FileUtil.DeleteFileOrDirectory(tempPath); #endif }
void Init() { AssetBundle assetBundle = AssetBundle.LoadFromFile(CustomAssetBundleManifest.PlaformPath); if (assetBundle == null) { throw new System.Exception("failed to create manifest assetBundle"); } var text = assetBundle.LoadAsset <TextAsset>(AssetBundleConfig.ManifestName); if (text == null) { throw new System.Exception("failed to load manifest"); } Manifest = CustomAssetBundleManifest.CreateInstance(text.bytes); PathPaser = new AssetBundlePathPaser(Manifest.AssetMap); }
public static CustomAssetBundleManifest CreateInstance(string text) { var manifest = new CustomAssetBundleManifest(); manifest.AssetMap = new Dictionary <string, AssetBundleInfo>(); JsonData jd = JsonMapper.ToObject(text.Trim()); manifest.IsCompressed = System.Convert.ToBoolean(jd["compress"].ToString()); JsonData jdManifest = jd["manifest"]; for (int i = 0; i < jdManifest.Count; i++) { var assetBundleInfo = new AssetBundleInfo(); assetBundleInfo.JsonDeserialize(jdManifest[i]); manifest.AssetMap[assetBundleInfo.relativePath] = assetBundleInfo; } return(manifest); }
public static List <string> GetSame(CustomAssetBundleManifest lh, CustomAssetBundleManifest rh) { List <string> list = new List <string>(); if (lh == null || rh == null) { return(list); } using (var itr = rh.AssetMap.GetEnumerator()) { while (itr.MoveNext()) { string key = itr.Current.Key; if (lh.Exists(key) && lh.GetMD5(key) == rh.GetMD5(key)) { list.Add(key); } } } return(list); }
IEnumerator PrepareTask(System.Action finishCallback, System.Action loadFailCallback, bool onlineUpdate = false) { bool err = false; bool hasTempCopy = false; NetworkReachability netState = Application.internetReachability; bool isGameReadyToComplete = PlayerPrefs.GetInt("GameReadyToComplete", 0) == 1; _progress.CurrentState = ProgressState.Init; CustomAssetBundleManifest tempManifest = null; CustomAssetBundleManifest localManifest = null; CustomAssetBundleManifest serverManifest = null; #region prepare manifest file string scenePath = System.IO.Path.Combine(AssetBundleConfig.PersistentDataPath, "Scene.unity3d").Replace("\\", "/"); string tempManifestPath = System.IO.Path.Combine(AssetBundleConfig.PersistentDataPathTemp, AssetBundleConfig.ManifestRelativePath).Replace("\\", "/"); string localManifestPath = System.IO.Path.Combine(AssetBundleConfig.PersistentDataPath, AssetBundleConfig.ManifestRelativePath).Replace("\\", "/"); string serverManifestPath = System.IO.Path.Combine(AssetBundleConfig.ServerAssetsPath, AssetBundleConfig.ManifestRelativePath).Replace("\\", "/"); #region 获取默认的manifest,PersistentDataPath/Temp //temp manifest--- a copy of manifest in streamassets if (!File.Exists(tempManifestPath) || !isGameReadyToComplete) { Debug.Log("temp copy of manifest"); yield return(StartCoroutine(Helpers.PathUtil.CopyFileFromAppPathAsync(AssetBundleConfig.ManifestRelativePath, AssetBundleConfig.StreamingAssetsPath, AssetBundleConfig.PersistentDataPathTemp))); } if (!File.Exists(tempManifestPath)) { yield return(null); } TextAsset tempTextAsset = LoadLocalAsset <TextAsset>(tempManifestPath, AssetBundleConfig.ManifestName); if (tempTextAsset != null) { Debug.Log("has temp copy"); hasTempCopy = true; tempManifest = CustomAssetBundleManifest.CreateInstance(tempTextAsset.bytes); } #endregion #region 获取本地manifest,PersistentDataPath //local manifest if (System.IO.File.Exists(localManifestPath) && isGameReadyToComplete) { Debug.Log("have localmanifest"); tempTextAsset = LoadLocalAsset <TextAsset>(localManifestPath, AssetBundleConfig.ManifestName); localManifest = CustomAssetBundleManifest.CreateInstance(tempTextAsset.bytes); } #endregion #region 获取资源服务器manifest,ServerPath //server manifest if (netState != NetworkReachability.NotReachable && onlineUpdate) { PlayerPrefs.SetInt("GameReadyToComplete", 0); yield return(null); string sourcePath = Path.Combine(AssetBundleConfig.ServerAssetsPath, AssetBundleConfig.ManifestRelativePath).Replace("\\", "/"); using (UnityWebRequest www = UnityWebRequest.Get(sourcePath)) { //www.timeout = 30;//设置超时,www.SendWebRequest()连接超时会返回,且isNetworkError为true yield return(www.SendWebRequest()); if (www.isNetworkError) { Debug.Log("Download Error:" + www.error); err = true; } else //if (www.responseCode == 200)//200表示接受成功 { Debug.Log("Download no error"); byte[] bytes = www.downloadHandler.data; Helpers.PathUtil.CopyBufferToFile(bytes, localManifestPath); var ab = AssetBundle.LoadFromMemory(bytes); var tx = ab.LoadAsset <TextAsset>(AssetBundleConfig.ManifestName); serverManifest = CustomAssetBundleManifest.CreateInstance(tx.bytes); ab.Unload(true); } } } #endregion #region 非网络状态检查本地manifest if (err || netState == NetworkReachability.NotReachable || !onlineUpdate) { err = false; if (localManifest != null && isGameReadyToComplete) //包含完整本地资源 { } else if (localManifest == null && hasTempCopy) //包含默认资源 { Debug.Log("包含默认资源"); Helpers.PathUtil.CopyFile(tempManifestPath, localManifestPath); } else //没有任何资源 { //throw new Exception("not contain default resources"); err = true; } } #endregion #endregion if (err) { loadFailCallback(); } else { bool IsCompressed = true; List <string> needLoadFromServer = new List <string>(); List <string> needLoadFromDefault = new List <string>(); if (serverManifest != null) { IsCompressed = serverManifest.IsCompressed; if (!isGameReadyToComplete && localManifest != null)//上次更新资源没有完全准备好 { localManifest.AssetMap.Clear(); } List <string> loadFromServer = CustomAssetBundleManifest.GetDifference(localManifest, serverManifest); List <string> canLoadFromDefault = CustomAssetBundleManifest.GetSame(tempManifest, serverManifest); foreach (var item in loadFromServer) { if (canLoadFromDefault.Contains(item)) { needLoadFromDefault.Add(item); } else { Debug.Log("needloadfromserver:" + item); needLoadFromServer.Add(item); } } } else if (localManifest == null && hasTempCopy) { IsCompressed = tempManifest.IsCompressed; List <string> loadFromDefault = new List <string>(); using (var itr = tempManifest.AssetMap.GetEnumerator()) { while (itr.MoveNext()) { loadFromDefault.Add(itr.Current.Key); } } needLoadFromDefault = loadFromDefault; } else if (localManifest != null && hasTempCopy) { IsCompressed = tempManifest.IsCompressed; needLoadFromDefault = GetLocalWithDefaultDifference(localManifest, tempManifest); Debug.Log("PathHelper.CopyFile"); Helpers.PathUtil.CopyFile(tempManifestPath, localManifestPath); } _progress.CurrentStep = 0; _progress.AllStepCount = needLoadFromDefault.Count + needLoadFromServer.Count; Debug.Log("allstepcount:" + _progress.AllStepCount + needLoadFromDefault.Count + needLoadFromServer.Count); if (serverManifest != null) { yield return(StartCoroutine(DownloadAssetBundle(needLoadFromServer, AssetBundleConfig.ServerAssetsPath, AssetBundleConfig.PersistentDataPath, IsCompressed))); } yield return(StartCoroutine(CopyAssetBundle(needLoadFromDefault, AssetBundleConfig.PersistentDataPath, IsCompressed))); _progress.CurrentState = ProgressState.Done; Helpers.PathUtil.DeleteDir(AssetBundleConfig.PersistentDataPathTemp); PlayerPrefs.SetInt("GameReadyToComplete", 1); yield return(null); if (finishCallback != null) { finishCallback(); } Destroy(gameObject); } }