Exemple #1
0
        /// <summary>
        /// 删除未使用的AB,可能是上次打包出来的,而这一次没生成的
        /// </summary>
        private void RemoveUnused()
        {
            var all = context.allTarget;
            HashSet <string> usedSet = new HashSet <string>();

            for (int i = 0; i < all.Count; i++)
            {
                ABTarget target = all[i];
                if (target.needSelfExport)
                {
                    usedSet.Add(target.bundleName);
                }
            }

            DirectoryInfo di = new DirectoryInfo(ABExportConst.PlatformBundleSavePath);;

            FileInfo[] abFiles = di.GetFiles("*.ab");
            for (int i = 0; i < abFiles.Length; i++)
            {
                FileInfo fi = abFiles[i];
                if (usedSet.Add(fi.Name))
                {
                    Debug.Log("Remove unused AB : " + fi.Name);

                    fi.Delete();
                    File.Delete(fi.FullName + ".manifest");
                }
            }
        }
Exemple #2
0
        public override void Save(Stream stream, ABTarget[] targets)
        {
            StreamWriter sw = new StreamWriter(stream);

            //写入文件头判断文件类型用,ABDT 意思即 Asset-Bundle-Data-Text
            sw.WriteLine("ABDT");

            for (int i = 0; i < targets.Length; i++)
            {
                ABTarget           target = targets[i];
                HashSet <ABTarget> deps   = target.GetAllDependencies();

                sw.WriteLine(target.assetPath);          // debug name
                sw.WriteLine(target.bundleName);         // bundle name
                sw.WriteLine(target.fileHash);           // file hash
                sw.WriteLine((int)target.compositeType); // export type

                sw.WriteLine(deps.Count);
                foreach (ABTarget item in deps)
                {
                    sw.WriteLine(item.bundleName);
                }
                sw.WriteLine("<------------->");
            }
            sw.Close();
        }
Exemple #3
0
        /// <summary>
        /// 添加本对象的依赖
        /// </summary>
        /// <param name="target"></param>
        private void AddDepend(ABTarget target)
        {
            if (target == this || this.ContainsDepend(target))
            {
                return;
            }
            if (target.ContainsDepend(this))
            {
                Debug.LogError("出现循环依赖:" + target.bundleName + " 与 " + bundleName);
                return;
            }
            dependencies.Add(target);
            target.reverseDependencies.Add(this);

            //遍历依赖树依赖我的对象不需要再依赖该目标
            IEnumerable <ABTarget> cols = dependencies;

            cols = new ABTarget[] { target };
            foreach (var at in cols)
            {
                var e = reverseDependencies.GetEnumerator();
                while (e.MoveNext())
                {
                    ABTarget dc = e.Current;
                    if (dc == null)
                    {
                        continue;
                    }
                    dc.RemoveDepend(at);
                }
                e.Dispose();
            }
        }
Exemple #4
0
        /// <summary>
        /// 添加根目标
        /// </summary>
        /// <param name="fliter"></param>
        private void AddRootTarget(ABFliter fliter)
        {
            var files = fliter.GetFiles();

            files.ForEach((file) =>
            {
                var target = ABTarget.GetOrCreateTarget(context, file);
                if (target == null)
                {
                    Debug.LogError(file);
                    return;
                }
                target.exportType = ABExportType.Root;
            });
        }
Exemple #5
0
        private void GetDependecies(HashSet <ABTarget> targets)
        {
            var ie = dependencies.GetEnumerator();

            while (ie.MoveNext())
            {
                ABTarget target = ie.Current;
                if (target.needSelfExport)
                {
                    targets.Add(target);
                }
                else
                {
                    target.GetDependecies(targets);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// 是否已经依赖(遍历依赖树)
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        private bool ContainsDepend(ABTarget target)
        {
            if (dependencies.Contains(target))
            {
                return(true);
            }
            var e = dependencies.GetEnumerator();

            while (e.MoveNext())
            {
                if (e.Current.ContainsDepend(target))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #7
0
        /// <summary>
        /// 从上下文中获取或创建Target
        /// </summary>
        /// <param name="context"></param>
        /// <param name="file"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public static ABTarget GetOrCreateTarget(ABExportContext context, FileInfo file, System.Type t = null)
        {
            ABTarget target   = null;
            string   fullPath = file.FullName;
            int      index    = fullPath.IndexOf("Assets");

            if (index < 0)
            {
                return(null);
            }

            //通过assetPath寻找
            string assetPath = fullPath.Substring(index);

            if (context.TryGetTarget(assetPath, out target))
            {
                return(target);
            }

            UnityEngine.Object obj = t != null?AssetDatabase.LoadAssetAtPath(assetPath, t) : AssetDatabase.LoadMainAssetAtPath(assetPath);

            if (obj == null)
            {
                return(null);
            }

            //通过InstanceId寻找
            int instID = obj.GetInstanceID();

            if (context.TryGetTarget(instID, out target))
            {
                return(target);
            }

            //创建新的Target
            target         = new ABTarget(obj, file, assetPath);
            target.context = context;

            context.AddTarget(target);

            return(target);
        }
Exemple #8
0
        public override void Save(Stream stream, ABTarget[] targets)
        {
            BinaryWriter sw = new BinaryWriter(stream);

            //写入文件头判断文件类型用,ABDB 意思即 Asset-Bundle-Data-Binary
            sw.Write(new char[] { 'A', 'B', 'D', 'B' });

            List <string> bundleNames = new List <string>();

            for (int i = 0; i < targets.Length; i++)
            {
                ABTarget target = targets[i];
                bundleNames.Add(target.bundleName);
            }

            //写入文件名池
            sw.Write(bundleNames.Count);
            for (int i = 0; i < bundleNames.Count; i++)
            {
                sw.Write(bundleNames[i]);
            }

            //写入详细信息
            for (int i = 0; i < targets.Length; i++)
            {
                ABTarget           target = targets[i];
                HashSet <ABTarget> deps   = target.GetAllDependencies();

                sw.Write(target.assetPath);                       //debug name
                sw.Write(bundleNames.IndexOf(target.bundleName)); //bundle name
                sw.Write(target.fileHash);                        //file hash
                sw.Write((int)target.compositeType);              //export type

                sw.Write(deps.Count);
                foreach (ABTarget item in deps)
                {
                    sw.Write(bundleNames.IndexOf(item.bundleName));
                }
            }
            sw.Close();
        }
Exemple #9
0
        /// <summary>
        /// 进行最后的导出操作
        /// </summary>
        /// <param name="exportDir"></param>
        private void Export(string exportDir)
        {
            var allTarget = context.allTarget;

            //标记所有 asset bundle name,如果需要单独打包则标出assetbundle名
            for (int i = 0; i < allTarget.Count; i++)
            {
                ABTarget      target   = allTarget[i];
                AssetImporter importer = AssetImporter.GetAtPath(target.assetPath);
                if (!importer)
                {
                    continue;
                }
                importer.assetBundleName = target.needSelfExport ? target.bundleName : null;
            }

            var bundleSavePath = ABExportConst.PlatformBundleSavePath + "/" + exportDir;

            PathEx.MakeDirectoryExist(bundleSavePath);
            AssetDatabase.Refresh();

            //开始打包
            BuildPipeline.BuildAssetBundles(bundleSavePath, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);

            //清除所有 asset bundle name
            for (int i = 0; i < allTarget.Count; i++)
            {
                ABTarget target = allTarget[i];
                if (!target.needSelfExport)
                {
                    continue;
                }
                AssetImporter importer = AssetImporter.GetAtPath(target.assetPath);
                if (!importer)
                {
                    continue;
                }
                importer.assetBundleName = null;
            }
        }
Exemple #10
0
        /// <summary>
        /// 保存依赖文件
        /// </summary>
        /// <param name="fliter"></param>
        private void SaveDep(string exportDirectory)
        {
            var all  = context.allTarget;
            var path = PathEx.Combine(ABExportConst.PlatformBundleSavePath, exportDirectory,
                                      ABPathResolver.DEPEND_FILE_NAME);

            if (File.Exists(path))
            {
                File.Delete(path);
            }
            List <ABTarget> exportList = new List <ABTarget>();

            for (int i = 0; i < all.Count; i++)
            {
                ABTarget target = all[i];
                if (target.needSelfExport)
                {
                    exportList.Add(target);
                }
            }
            dataWriter.Save(path, exportList.ToArray());
        }
Exemple #11
0
        /// <summary>
        /// 分析关系依赖
        /// </summary>
        public void Analyze()
        {
            if (isAnalyzed)
            {
                return;
            }
            isAnalyzed = true;

            //得到依赖
            UnityEngine.Object[] deps = EditorUtility.CollectDependencies(new UnityEngine.Object[] { asset });

            var depList = from dep in deps
                          let path = AssetDatabase.GetAssetPath(dep)
                                     where !(dep is MonoScript || path.StartsWith("Resources"))
                                     select AssetDatabase.GetAssetPath(dep);

            string[] paths = depList.Distinct().ToArray();

            paths.Foreach <string>((path) =>
            {
                if (!File.Exists(path))
                {
                    return;
                }

                FileInfo fileInfo = new FileInfo(path);
                ABTarget target   = GetOrCreateTarget(context, fileInfo);
                if (target == null)
                {
                    return;
                }

                AddDepend(target);
                target.Analyze();
            });
        }
Exemple #12
0
 /// <summary>
 /// 尝试获取ABTarget
 /// </summary>
 /// <param name="assetPath"></param>
 /// <param name="target"></param>
 /// <returns></returns>
 public bool TryGetTarget(string assetPath, out ABTarget target)
 {
     return(assetPath2target.TryGetValue(assetPath, out target));
 }
Exemple #13
0
 /// <summary>
 /// 尝试获取ABTarget
 /// </summary>
 /// <param name="instanceId"></param>
 /// <param name="target"></param>
 /// <returns></returns>
 public bool TryGetTarget(int instanceId, out ABTarget target)
 {
     return(object2target.TryGetValue(instanceId, out target));
 }
Exemple #14
0
 /// <summary>
 /// 将Target从上下文中移除
 /// </summary>
 /// <param name="target"></param>
 public static void RemoveTarget(ABTarget target)
 {
     target.context.RemoveTarget(target);
 }
Exemple #15
0
 /// <summary>
 /// 从依赖本对象的依赖列表中移除
 /// </summary>
 /// <param name="target"></param>
 private void RemoveReverseDepend(ABTarget target)
 {
     target.RemoveDepend(this);
 }
Exemple #16
0
 /// <summary>
 /// 移除本对象的依赖项
 /// </summary>
 /// <param name="target"></param>
 private void RemoveDepend(ABTarget target)
 {
     dependencies.Remove(target);
     target.reverseDependencies.Remove(this);
 }
Exemple #17
0
 /// <summary>
 /// 添加Target
 /// </summary>
 /// <param name="target"></param>
 public void AddTarget(ABTarget target)
 {
     assetPath2target[target.assetPath]          = target;
     object2target[target.asset.GetInstanceID()] = target;
 }
Exemple #18
0
 /// <summary>
 /// 移除Target
 /// </summary>
 /// <param name="target"></param>
 public void RemoveTarget(ABTarget target)
 {
     assetPath2target.Remove(target.assetPath);
     object2target.Remove(target.asset.GetInstanceID());
 }
Exemple #19
0
 /// <summary>
 /// 向依赖本对象的依赖列表中添加项
 /// </summary>
 /// <param name="target"></param>
 private void AddReverseDepend(ABTarget target)
 {
     target.AddDepend(this);
 }