private IEnumerator ReadAssetBundleFileCoroutine(Stream stream, Action<Byte[], ECAssetBundleHeader> onFinish) { if (stream == null) { //失败 if (onFinish != null) onFinish(null, null); yield break; } ECAssetBundleHeader bh = new ECAssetBundleHeader(); bh.Load(stream); Byte[] fileData = new Byte[stream.Length-stream.Position]; stream.Read(fileData, 0, fileData.Length); stream.Dispose(); //stream 已经用完了。由于是异步操作,只能由调用者释放 if (onFinish != null) onFinish(fileData, bh); }
public static void LoadAssetBundleImmediate(String path, Action<AssetBundle, ECAssetBundleHeader, bool> onFinish) { Stream stream = FileLoader.LoadFile(path); if (stream == null) { //Debug.LogError("failed to open asset bundle file: " + path); //在回调里自行处理 } ECAssetBundleHeader bh = new ECAssetBundleHeader(); bh.Load(stream); CreateBundleImmediate(stream, bh, onFinish, path); }
static bool SaveSepFileToCache(Stream stream, string sepFilePath, string depFilePath, out ECAssetBundleHeader bh) { bh = new ECAssetBundleHeader(); bh.Load(stream); if ((bh.option & ECAssetBundleHeader.BundleOption.SepFile) != 0) { int headerLen = (int)stream.Position; String sepDir = Path.GetDirectoryName(sepFilePath); Directory.CreateDirectory(sepDir); stream.Seek(-headerLen, SeekOrigin.Current); WriteStreamToFile(depFilePath, stream, headerLen); //保存 assetbundle WriteStreamToFile(sepFilePath, stream, (int)(stream.Length - stream.Position)); return true; } return false; }
public static void LoadAssetBundleFromSepFile(String path, string depFilePath, Action<AssetBundle, ECAssetBundleHeader, bool> onFinish) { ECAssetBundleHeader bh; using (FileStream fin = File.OpenRead(depFilePath)) { bh = new ECAssetBundleHeader(); bh.Load(fin); } AssetBundle bundle = AssetBundle.CreateFromFile(path); if (onFinish != null) onFinish(bundle, bh, true); }
private static IEnumerator LoadAssetBundleCoroutine(Stream stream, Action<AssetBundle, ECAssetBundleHeader, bool> onFinish, String path) { ECAssetBundleHeader bh = new ECAssetBundleHeader(); bh.Load(stream); CreateBundleImmediate(stream, bh, onFinish, path); yield break; }
//stream is not null private static void CreateBundleImmediate(Stream stream, ECAssetBundleHeader bh, Action<AssetBundle, ECAssetBundleHeader, bool> onFinish, String path) { if (stream == null) { //失败 if (onFinish != null) onFinish(null, null, false); return; } Byte[] fileData; using (stream) //由于是异步操作,由调用者释放 { fileData = new Byte[stream.Length - stream.Position]; stream.Read(fileData, 0, fileData.Length); stream.Dispose(); //stream 已经用完了。由于是异步操作,只能由调用者释放 } ResourceManager.LogCreateFromMemoryImmediateBegin(); AssetBundle bundle = AssetBundle.CreateFromMemoryImmediate(fileData); ResourceManager.LogCreateFromMemoryImmediateEnd(path); fileData = null; if (onFinish != null) onFinish(bundle, bh, false); }
private static IEnumerator AsyncLoadAssetBundleCoroutine(Stream stream, ECAssetBundleHeader bh, Action<AssetBundle, ECAssetBundleHeader, bool> onFinish, String path) { if (stream == null) { //失败 if (onFinish != null) onFinish(null, null, false); yield break; } Byte[] fileData; using (stream) //由于是异步操作,由调用者释放 { fileData = new Byte[stream.Length - stream.Position]; stream.Read(fileData, 0, fileData.Length); stream.Dispose(); //stream 已经用完了。由于是异步操作,只能由调用者释放 } AssetBundleCreateRequest request = AssetBundle.CreateFromMemory(fileData); fileData = null; if (request == null) { if (onFinish != null) onFinish(null, null, false); yield break; } while (!request.isDone) yield return null; if (request.assetBundle == null) { if (onFinish != null) onFinish(null, null, false); yield break; } if (onFinish != null) onFinish(request.assetBundle, bh, false); }
public static void LoadAssetBundleImmediate(String path, Action<AssetBundle, ECAssetBundleHeader, bool> onFinish) { Stream stream = LoadFile(path); if (stream == null) { if (onFinish != null) onFinish(null, null, false); return; } ECAssetBundleHeader bh = new ECAssetBundleHeader(); bh.Load(stream); CreateBundleImmediate(stream, bh, onFinish, path); }
public static void LoadAssetBundleFromSepFile(String path, string depFilePath, Action<AssetBundle, ECAssetBundleHeader, bool> onFinish) { ECAssetBundleHeader bh; try { using (FileStream fin = File.OpenRead(depFilePath)) { bh = new ECAssetBundleHeader(); bh.Load(fin); } } catch (IOException e) { Debug.LogWarning("LoadAssetBundleFromSepFile failed to read header from " + depFilePath + ": " + e); if (onFinish != null) onFinish(null, null, false); return; } catch (System.IO.IsolatedStorage.IsolatedStorageException e) { Debug.LogWarning("LoadAssetBundleFromSepFile failed to read header from " + depFilePath + ": " + e); if (onFinish != null) onFinish(null, null, false); return; } AssetBundle bundle = AssetBundle.CreateFromFile(path); if (onFinish != null) onFinish(bundle, bh, true); }
public static void BuildToOneBundle(Object realass, string path, bool recursive) { if (CheckModify && recursive) { if (!CheckAssetModify(realass, path, true)) return; } int AssetCount = 0; List<ECAssetBundleHeader.DepInfo> ls = new List<ECAssetBundleHeader.DepInfo>(); string asspath = AssetDatabase.GetAssetPath(realass); if (recursive) { string[] deppaths = AssetDatabase.GetDependencies(new string[] { asspath }); Dictionary<string, bool> realdeps = new Dictionary<string, bool>(); foreach (string realdep in deppaths) { realdeps[realdep] = true; } Object[] depobjs = EditorUtility.CollectDependencies(new Object[] { realass }); BuildPipeline.PushAssetDependencies(); AssetCount++; for (int i = 0; i < depobjs.Length; i++) { Object dep = depobjs[i]; if (ReferenceEquals(dep, realass)) continue; string texpath = AssetDatabase.GetAssetPath(dep); if (!realdeps.ContainsKey(texpath)) continue; if (dep is Texture || dep is Shader || dep is MonoScript || dep is Font) { if (!texpath.ToLower().EndsWith(".asset") && !string.IsNullOrEmpty(texpath)) { BuildToOneBundle(dep, path, false); ECAssetBundleHeader.DepInfo info = new ECAssetBundleHeader.DepInfo(); info.name = ""; string realname = ConvertFileName(texpath) + ".u3dext"; info.path = realname.ToLower(); ls.Add(info); } } } BuildPipeline.PushAssetDependencies(); AssetCount++; } string assetpath = ConvertFileName(Path.GetDirectoryName(asspath)); string outpath; if (asspath != "") { outpath = path + "/" + assetpath; } else outpath = assetpath; Directory.CreateDirectory(outpath); string guid = AssetDatabase.AssetPathToGUID(asspath); string outfile = outpath + "/" + guid; BuildAssetBundleOptions option; option = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies; option |= BuildAssetBundleOptions.UncompressedAssetBundle; bool suc = BuildPipeline.BuildAssetBundleExplicitAssetNames(new Object[] { realass }, new string[] { "1" }, outfile, option, ExportAssetBundles.CurBuildTarget); // do not compress font bool ForceSep = realass is Font; bool NeedSep = false; if (suc && !ForceSep) { FileInfo fi = new FileInfo(outfile); if (realass is AudioClip) { if (fi.Length > min_audio_clip_bundel_size) NeedSep = true; } else if (fi.Length > min_compress_bundle_size) { option = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies; suc = BuildPipeline.BuildAssetBundleExplicitAssetNames(new Object[] { realass }, new string[] { "1" }, outfile, option, ExportAssetBundles.CurBuildTarget); Debug.LogWarning("Big bundle: " + outfile + " Origin Size: " + fi.Length); } } for (int n = 0; n < AssetCount; n++) BuildPipeline.PopAssetDependencies(); if (suc) { byte[] content = File.ReadAllBytes(outfile); string outfile2 = outpath + "/" + Path.GetFileName(asspath) + ".u3dext"; using (FileStream fs = File.Open(outfile2, FileMode.Create, FileAccess.Write)) { ECAssetBundleHeader bh = new ECAssetBundleHeader(); if (ForceSep || NeedSep) bh.option |= ECAssetBundleHeader.BundleOption.SepFile; if (realass is Shader || realass is MonoScript || realass is Font) bh.option |= ECAssetBundleHeader.BundleOption.DonotRelease; bh.deps = ls.ToArray(); bh.Save(fs); fs.Write(content, 0, content.Length); } File.Delete(outfile); } else Debug.LogError("BuildAssetBundleExplicitAssetNames"); }
static void BuildOneAssetBundle(string expcur, Dictionary<string, int> objmark, Dictionary<string, List<string>> allobjchild, string path, ref int depcount) { // 假设已经输出则跳过 if (objmark.ContainsKey(expcur)) return; List<string> subs = allobjchild[expcur]; if (subs != null) { foreach (string sub in subs) { // 假设已经输出则跳过 if (objmark.ContainsKey(sub)) continue; BuildOneAssetBundle(sub, objmark, allobjchild, path, ref depcount); } } objmark[expcur] = 1; string asspath = expcur; if (string.IsNullOrEmpty(asspath)) return; string guid = AssetDatabase.AssetPathToGUID(asspath); string assetpath = ConvertFileName(Path.GetDirectoryName(asspath)); string outpath; if (asspath != "") { outpath = path + "/" + assetpath; } else outpath = assetpath; Directory.CreateDirectory(outpath); //string outfile = Path.Combine(outpath, Path.GetFileNameWithoutExtension(asspath)); string outfile = outpath + "/" + guid; BuildPipeline.PushAssetDependencies(); depcount++; Object realass = AssetDatabase.LoadMainAssetAtPath(expcur); if (realass == null) return; Object[] depobjs = EditorUtility.CollectDependencies(new Object[] { realass }); Dictionary<string, int> deppathmap = new Dictionary<string, int>(); foreach (Object depobj in depobjs) { string deppath = AssetDatabase.GetAssetPath(depobj); if (string.IsNullOrEmpty(deppath)) continue; deppathmap[deppath] = 1; } List<string> realsubs = new List<string>(); if (subs != null) { foreach (string sub in subs) { if (deppathmap.ContainsKey(sub)) { string realname = ConvertFileName(sub) + ".u3dext"; realsubs.Add(realname.ToLower()); } } } BuildAssetBundleOptions option; option = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies; option |= BuildAssetBundleOptions.UncompressedAssetBundle; bool suc = BuildPipeline.BuildAssetBundleExplicitAssetNames(new Object[] { realass }, new string[] { "1" }, outfile, option, ExportAssetBundles.CurBuildTarget); Debug.Log("src file: " + asspath + " " + depcount); if (/*realass is MonoScript || */!deppathmap.ContainsKey(expcur)) { File.Delete(outfile); } else if (suc) { // do not compress font bool ForceSep = realass is Font; bool NeedSep = false; if (!ForceSep) { FileInfo fi = new FileInfo(outfile); if (realass is AudioClip) { if (fi.Length > min_audio_clip_bundel_size) NeedSep = true; } else if (fi.Length > min_compress_bundle_size) { option = BuildAssetBundleOptions.DeterministicAssetBundle | BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies; suc = BuildPipeline.BuildAssetBundleExplicitAssetNames(new Object[] { realass }, new string[] { "1" }, outfile, option, ExportAssetBundles.CurBuildTarget); Debug.LogWarning("Big bundle: " + outfile + " Origin Size: " + fi.Length); } } byte[] content = File.ReadAllBytes(outfile); string outfile2 = outpath + "/" + Path.GetFileName(asspath) + ".u3dext"; _depmap[outfile2.ToLower()] = 1; var oldFileInfo = new FileInfo(outfile2); if (oldFileInfo.Exists) oldFileInfo.IsReadOnly = false; using (FileStream fs = File.Open(outfile2, FileMode.Create, FileAccess.Write)) { ECAssetBundleHeader bh = new ECAssetBundleHeader(); bool bDefault = true; if (ForceSep || NeedSep) bh.option |= ECAssetBundleHeader.BundleOption.SepFile; if (realass is Material) { bh.specialType = ECAssetBundleHeader.BundleSpecialType.Material; Material mt = realass as Material; if (mt.shader != null) { bDefault = false; List<string> pnames = new List<string>(); int nPCount = ShaderUtil.GetPropertyCount(mt.shader); for (int n = 0; n < nPCount; n++) { ShaderUtil.ShaderPropertyType spt = ShaderUtil.GetPropertyType(mt.shader, n); if (spt == ShaderUtil.ShaderPropertyType.TexEnv) { string pn = ShaderUtil.GetPropertyName(mt.shader, n); pnames.Add(pn); } } List<ECAssetBundleHeader.DepInfo> deplist = new List<ECAssetBundleHeader.DepInfo>(); foreach (var realsub in realsubs) { bool findtex = false; foreach (var texname in pnames) { Texture tex = mt.GetTexture(texname); if (tex) { string texpath = AssetDatabase.GetAssetPath(tex); if (!string.IsNullOrEmpty(texpath)) { string realpath = ConvertFileName(texpath) + ".u3dext"; realpath = realpath.ToLower(); if (realpath == realsub) { ECAssetBundleHeader.DepInfo info = new ECAssetBundleHeader.DepInfo(); info.name = texname; info.path = realsub; deplist.Add(info); findtex = true; } } } } if (!findtex) { ECAssetBundleHeader.DepInfo info = new ECAssetBundleHeader.DepInfo(); info.name = ""; info.path = realsub; deplist.Add(info); } } bh.deps = deplist.ToArray(); } } else if (realass is Texture) { bh.option |= ECAssetBundleHeader.BundleOption.ManuallyResolve; bh.specialType = ECAssetBundleHeader.BundleSpecialType.Texture; } else if (realass is Shader) { bh.option |= ECAssetBundleHeader.BundleOption.DonotRelease; } else if (realass is MonoScript) { bh.option |= ECAssetBundleHeader.BundleOption.DonotRelease; } else if (realass is Font) { bh.option |= ECAssetBundleHeader.BundleOption.DonotRelease; } if (bDefault) { bh.deps = new ECAssetBundleHeader.DepInfo[realsubs.Count]; for (int n = 0; n < realsubs.Count; n++) { bh.deps[n].name = ""; bh.deps[n].path = realsubs[n]; } } bh.Save(fs); fs.Write(content, 0, content.Length); } File.Delete(outfile); } }