在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → ab打包

ab打包

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:4.05KB
  • 下载次数:2
  • 浏览次数:44
  • 发布时间:2020-10-20
  • 实例类别:C#语言基础
  • 发 布 人:luorensheng1
  • 所需积分:2
 相关标签: AB

实例介绍

【实例简介】
【实例截图】

【核心代码】

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Linq;

public class AssetbundlePackat
{
    //把需要热更的Resources资源放入HotUpdate文件夹,如果需要默认读取resources/HotUpdate下的资源
    //,请不要添加到LevelVersion.xml版本中,也不要生成ab包,等需要热更修改内容时,再包含进去版本中,并生成ab包
    //注意:不要为了省时间,只打一个需要的ab包,需要整体重新打ab包,因为会生成ab依赖分析包

    static string m_beginPath;
    static string beginPath
    {
        get
        {
            if (string.IsNullOrEmpty(m_beginPath))
            {
                int index = Application.dataPath.LastIndexOf("Assets");
                m_beginPath = Application.dataPath.Remove(index);
            }

            return m_beginPath;
        }
    }


    #region 清除AssetBundle包名
    [MenuItem("HotTools/ClearAbName")]
    static void ClearABNames()
    {
        //清除旧的ab包名
        EditorUtility.DisplayProgressBar("搜索ab包名", "进行中...", 0.2f);
        string[] abnames = AssetDatabase.GetAllAssetBundleNames();
        for(int i=0;i<abnames.Length;i  )
        {
            EditorUtility.DisplayProgressBar("清除ab包名", abnames[i], (i 1f) / abnames.Length);
            AssetDatabase.RemoveAssetBundleName(abnames[i], true);
        }

        EditorUtility.ClearProgressBar();

    }

    #endregion

    #region 设置AssetBundle包名
    const int ReferenceThreshold = 2;//大于阀值设置ab名字,不被包含,而被依赖

    static int objDependencieCount = 0;//依赖计数
    static Dictionary<string, bool> dicAtlasSetAbNameFlag = new Dictionary<string,bool>();//图集设置assetName标识
    static Dictionary<string, Dictionary<string,bool>> dicObjRelyNum = new Dictionary<string, Dictionary<string,bool>>();//key=objPath value=依赖列表
    static Dictionary<string, Dictionary<string,bool>> dicAtlasObjRelyNum = new Dictionary<string, Dictionary<string,bool>>();//key=packing Tag value=依赖列表



    static void InitSetAssetBundle()
    {
        AssetDatabase.SaveAssets();
        objDependencieCount = 0;
        dicAtlasSetAbNameFlag.Clear();
        dicObjRelyNum.Clear();
        dicAtlasObjRelyNum.Clear();
        dicSpritePackingTagList.Clear();
        GetSpriteListAtPackingTag(Application.dataPath);
    }

    #region packing Tag sprite列表



    static Dictionary<string, List<string>> dicSpritePackingTagList = new Dictionary<string, List<string>>();//packing Tag sprite列表
    static void GetSpriteListAtPackingTag(string path)
    {
        string[] filePaths = Directory.GetFiles(path);
        List<string> ignoreExtens = new List<string> { "", ".lua", ".cs", ".dll", ".json", ".mat", ".meta", ".DS_Store", ".text", ".xml", ".prefab", ".ab", ".mp4", ".mp3" };
        for (int i=0;i<filePaths.Length;i  )
        {
            string fp = filePaths[i];

            string exten = Path.GetExtension(fp);
            if (ignoreExtens.Contains(exten)) continue;
            string relativePath = fp.Replace(Application.dataPath, "Assets");

            EditorUtility.DisplayProgressBar("分析图集Sprite", relativePath, ((float)i) / filePaths.Length);


            AssetImporter aImport = AssetImporter.GetAtPath(relativePath);
            TextureImporter ti = aImport as TextureImporter;

            if (ti != null && ti.textureType == TextureImporterType.Sprite)
            {
                ti.isReadable = false;

                if (!dicSpritePackingTagList.ContainsKey(ti.spritePackingTag))
                    dicSpritePackingTagList.Add(ti.spritePackingTag, new List<string>());

                dicSpritePackingTagList[ti.spritePackingTag].Add(relativePath);
            }
        }

        string[] direPaths = Directory.GetDirectories(path);
        foreach (var d in direPaths)
        {
            if (Path.GetDirectoryName(d) == "Editor") continue;

            GetSpriteListAtPackingTag(d);
        }
    }

    #endregion


    /// <summary>
    /// 热更新目录
    /// </summary>

    const string ScenesDirector = "/Scenes";

    /// <summary>
    /// 分析依赖
    /// </summary>
    static void AnalyzeRely()
    {
        InitSetAssetBundle();

        DirectoryInfo dirinfo=null;

        #region Resources文件夹下资源对象

        string resourceHotDire = string.Format("{0}/Resources/{1}", Application.dataPath, HotDataContext.HotDirector);
        //现在Resources文件夹找需要打ab的资源
        if (Directory.Exists(resourceHotDire))
            dirinfo = new DirectoryInfo(resourceHotDire);
        else if (Directory.Exists(string.Format("{0}/{1}", Application.dataPath, HotDataContext.HotDirector)))
            dirinfo = new DirectoryInfo(string.Format("{0}/{1}",Application.dataPath, HotDataContext.HotDirector));

        if (dirinfo != null)
        {
            FileInfo[] fs = dirinfo.GetFiles("*.*", SearchOption.AllDirectories);
            foreach (FileInfo f in fs)
            {
                string ext_name = Path.GetExtension(f.Name);
                if (ext_name == ".meta" || ext_name == ".DS_Store") continue;

                string path = f.FullName.Replace("\\", "/");
                string relativalPath = path.Replace(Application.dataPath, "Assets");

                ObjDependencie(string.Empty, relativalPath);
            }
        }

        #endregion

        #region Scenes文件

        EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
        if (Directory.Exists(Application.dataPath   ScenesDirector))
        {
            dirinfo = new DirectoryInfo(Application.dataPath   ScenesDirector);

            FileInfo[] fs = dirinfo.GetFiles("*.unity", SearchOption.TopDirectoryOnly);
            foreach (FileInfo f in fs)
            {
                string path = f.FullName.Replace("\\", "/");
                string relativalPath = path.Replace(Application.dataPath, "Assets");

                for (int i = 0; i < scenes.Length; i  )
                {
                    EditorBuildSettingsScene scene = scenes[i];
                    if (scene.path.Equals(relativalPath))
                        ObjDependencie(string.Empty, relativalPath);
                }

            }
        }


        #endregion
    }


    [MenuItem("HotTools/SetAbName")]
    static void SetAssetBundleName()
    {

        //把图集建立启用Editor->Project Settings->Editor->Sprote Packer Mode Enabled

        //清除旧的ab包名
        //ClearABNames();


        AnalyzeRely();//分析依赖
        SetAbName();
    }

    static void SetAbName()
    {
        int curProgress = 0;
        float totalProgress = dicObjRelyNum.Count   dicAtlasObjRelyNum.Count;

        foreach (string objPath in dicObjRelyNum.Keys)
        {
            EditorUtility.DisplayProgressBar("设置ab包名", objPath,   curProgress / totalProgress);
            if (!dicObjRelyNum[objPath].ContainsKey(string.Empty) && dicObjRelyNum[objPath].Count < ReferenceThreshold) continue;


            string exten = Path.GetExtension(objPath);
            string newExten = exten.Replace('.', '_');
            string assetbundleName = objPath.Replace(exten, newExten);
            assetbundleName = assetbundleName.Replace('/', '.');

            AssetImporter aImport = AssetImporter.GetAtPath(objPath);
            aImport.SetAssetBundleNameAndVariant(assetbundleName   ".ab", string.Empty);
        }

        //图集
        foreach (string packingTag in dicAtlasObjRelyNum.Keys)
        {
            EditorUtility.DisplayProgressBar("设置ab包名", packingTag,   curProgress / totalProgress);
            if (dicAtlasObjRelyNum[packingTag].Count < ReferenceThreshold) continue;

            //if (dicAtlasObjRelyNum[packingTag] < Threshold) continue;
            List<string> list = dicSpritePackingTagList[packingTag];
            for (int i = 0; i < list.Count; i  )
            {
                AssetImporter tempImport = AssetImporter.GetAtPath(list[i]);
                tempImport.SetAssetBundleNameAndVariant(packingTag   "_atlas"   ".ab", string.Empty);// 图集格式:atlas
            }
        }

        EditorUtility.ClearProgressBar();

        AssetDatabase.SaveAssets();
    }

    static void ObjDependencie(string referenceObjPath,string objPath)
    {
        EditorUtility.DisplayProgressBar("正在分析依赖"  objDependencieCount  , objPath, 0);

        AssetImporter aImport= AssetImporter.GetAtPath(objPath);
        TextureImporter ti = aImport as TextureImporter;

        if (ti != null && ti.textureType == TextureImporterType.Sprite)
        {
            if (!dicAtlasSetAbNameFlag.ContainsKey(ti.spritePackingTag))
            {
                dicAtlasSetAbNameFlag.Add(ti.spritePackingTag, true);
                dicAtlasObjRelyNum.Add(ti.spritePackingTag, new Dictionary<string, bool>());
            }
            
            if(!dicAtlasObjRelyNum[ti.spritePackingTag].ContainsKey(referenceObjPath))dicAtlasObjRelyNum[ti.spritePackingTag].Add(referenceObjPath,true);
            return;
        }


        if (!dicObjRelyNum.ContainsKey(objPath)) dicObjRelyNum.Add(objPath, new Dictionary<string, bool>());
        if(!dicObjRelyNum[objPath].ContainsKey(referenceObjPath)) dicObjRelyNum[objPath].Add(referenceObjPath, true);


        string[] relyPathArr = AssetDatabase.GetDependencies(objPath, false);
        foreach (string relyObjPath in relyPathArr)
        {
            if (objPath == relyObjPath) continue;//原对象本身,不依赖自己
            string exten = Path.GetExtension(relyObjPath);

            if (exten == ".cs") continue;
            if (exten == ".dll") continue;

            ObjDependencie(objPath,relyObjPath);
        }
    }
    #endregion



    [MenuItem("HotTools/所选物体设置AbName")]
    static void SelectObjectSetAbName()
    {
        ClearABNames();
        InitSetAssetBundle();
        List<string> relativalPathList = new List<string>();
        EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
        Object[] objs= Selection.objects;
        foreach (var obj in objs)
        {
            string relativalPath= AssetDatabase.GetAssetPath(obj);
            string path= beginPath   AssetDatabase.GetAssetPath(obj);

            bool resourceHot = relativalPath.IndexOf("Assets/Resources/"   HotDataContext.HotDirector) == 0;
            bool isScene = relativalPath.IndexOf("Assets/Scenes") == 0;
            if (resourceHot || isScene)
            {
                if (Directory.Exists(path))
                {
                    DirectoryInfo dirinfo = new DirectoryInfo(path);

                    FileInfo[] fs = dirinfo.GetFiles("*.*", SearchOption.AllDirectories);
                    foreach (FileInfo f in fs)
                    {
                        string ext_name = Path.GetExtension(f.Name);
                        if (ext_name == ".meta" || ext_name == ".DS_Store") continue;
                        string childRelativalPath = f.FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets");

                        if (isScene)
                        {
                            if (childRelativalPath.IndexOf("Assets/Scenes/Fix/") != -1) continue;
                            for (int i = 0; i < scenes.Length; i  )
                            {
                                EditorBuildSettingsScene scene = scenes[i];
                                if (scene.path.Equals(childRelativalPath) &&
                                    !relativalPathList.Contains(childRelativalPath))
                                    relativalPathList.Add(childRelativalPath);
                            }
                        }
                        else if (!relativalPathList.Contains(childRelativalPath))
                            relativalPathList.Add(childRelativalPath);

                    }

                }
                else if (File.Exists(path))
                {
                    if (isScene)
                    {
                        if (relativalPath.IndexOf("Assets/Scenes/Fix/") != -1) continue;

                        for (int i = 0; i < scenes.Length; i  )
                        {
                            EditorBuildSettingsScene scene = scenes[i];
                            if (scene.path.Equals(relativalPath)&&
                                !relativalPathList.Contains(relativalPath))
                                relativalPathList.Add(relativalPath);
                        }
                    }
                    else
                    {
                        if (!relativalPathList.Contains(relativalPath))
                            relativalPathList.Add(relativalPath);
                    }
                }
            }
        }

        foreach (var relativalPath in relativalPathList)
            ObjDependencie(string.Empty, relativalPath);

        SetAbName();
    }


    #region 建立AssetBundle
    [MenuItem("HotTools/建立AB包(Android)")]
    static void BuildAssetBundleAndroid()
    {
        BuildAssetBundle(BuildTarget.Android,false);
    }

    [MenuItem("HotTools/建立AB包(IOS)")]
    static void BuildAssetBundleIOS()
    {
        BuildAssetBundle(BuildTarget.iOS,false);
    }


    /// <summary>
    /// 建立ab包
    /// </summary>
    /// <param name="isReBuild">是否清空重新建立</param>
    static void BuildAssetBundle(BuildTarget buildTarget, bool isReBuild)
    {
        string tempAB = "";
        string hotUpdateSavePath = ""; 
        if (buildTarget == BuildTarget.Android)
        {
            tempAB = beginPath   "TempAB/Android";
            hotUpdateSavePath = beginPath   HotDataContext.HotDirector  "/Android";//string.Format("{0}/{1}", Application.streamingAssetsPath, HotDataContext.HotDirector);
        }
        else
        {
            tempAB = beginPath   "TempAB/Ios";
            hotUpdateSavePath= beginPath   HotDataContext.HotDirector "/Ios";
        }
        string outputPath = string.Format("{0}/{1}", hotUpdateSavePath, HotDataContext.Assetbundles);


        if (Directory.Exists(hotUpdateSavePath))
        {
            if (isReBuild)
            {
                Directory.Delete(hotUpdateSavePath, true);
                Directory.CreateDirectory(hotUpdateSavePath);
            }
        }
        else
            Directory.CreateDirectory(hotUpdateSavePath);


        if (Directory.Exists(tempAB))
        {
            if (isReBuild)
            {
                Directory.Delete(tempAB, true);
                Directory.CreateDirectory(tempAB);
            }
        }
        else
            Directory.CreateDirectory(tempAB);


        BuildPipeline.BuildAssetBundles(tempAB, BuildAssetBundleOptions.ChunkBasedCompression, buildTarget);//分平台打包,可自动切换平台


        if (Directory.Exists(outputPath))
        {
            DirectoryInfo dirinfo = new DirectoryInfo(outputPath);
            FileInfo[] fs = dirinfo.GetFiles("*.*", SearchOption.AllDirectories);
            foreach (FileInfo f in fs)
            {
                string ext_name = Path.GetExtension(f.Name);
                if (ext_name == ".meta" || ext_name == ".DS_Store") continue;
                File.Delete(f.FullName);
            }
        }else
            Directory.CreateDirectory(outputPath);

        //ab目录分类 场景(Scenes)、Resources(Resources)、其他依赖ab(Others)

        string abResources = string.Format("{0}/{1}", outputPath, HotDataContext.ResourcesDirector);
        string abScenes = string.Format("{0}/{1}", outputPath, HotDataContext.ScenesDirector);
        string abOhters= string.Format("{0}/{1}", outputPath, HotDataContext.OhtersDirector);

        if (!Directory.Exists(abResources)) Directory.CreateDirectory(abResources);
        if (!Directory.Exists(abScenes)) Directory.CreateDirectory(abScenes);
        if (!Directory.Exists(abOhters)) Directory.CreateDirectory(abOhters);

        string[] files = Directory.GetFiles(tempAB);
        int ii = 0;
        for (int i=0; i<files.Length; i  )
        {
            string filePath = files[i];
            string fileName = Path.GetFileName(filePath);
            string exten = Path.GetExtension(fileName);

            if (exten == ".manifest"||exten == ".meta") continue;
            ii  ;
            EditorUtility.DisplayProgressBar("重新导入", ii.ToString(), i/ (float)files.Length);

            if (fileName.IndexOf(HotDataContext.resourcesAbName) == 0)//Resources里文件
            {
                File.Copy(filePath, string.Format("{0}/{1}", abResources, fileName));
            }
            else if (fileName.Contains(HotDataContext.sceneExten))//场景类型
            {
                File.Copy(filePath, string.Format("{0}/{1}", abScenes, fileName));
            }
            else if (string.IsNullOrEmpty(exten))
            {
                //ab依赖描述
                File.Copy(filePath, string.Format("{0}/{1}", outputPath, HotDataContext.Assetbundles));
            }
            else
            {
                //其他依赖ab包
                File.Copy(filePath, string.Format("{0}/{1}", abOhters, fileName));
            }
        }

        EditorUtility.ClearProgressBar();

        AssetDatabase.Refresh();

        System.Diagnostics.Process.Start(hotUpdateSavePath);
    }



    #endregion

    #region 一键重新建立ab包
    [MenuItem("HotTools/一键重新建立AB包(Android)")]
    static void OneKeyBuildABAndroid()
    {
        ClearABNames();
        SetAssetBundleName();
        BuildAssetBundle(BuildTarget.Android,true);
    }

    [MenuItem("HotTools/一键重新建立AB包(IOS)")]
    static void OneKeyBuildABIOS()
    {
        ClearABNames();
        SetAssetBundleName();
        BuildAssetBundle(BuildTarget.iOS,true);
    }



    #endregion

}


标签: AB

实例下载地址

ab打包

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
;
报警