zoukankan      html  css  js  c++  java
  • 打包加载 AssetBundle

    1.先创建Asset序列化(单个文件夹所在文件夹路径,会遍历这个文件夹所有的Prefab,所有的Prefab名字不能重复,必须保证名字得唯一性),配置好ConfigAB表

    
    
    /*              #########                       
                  ############                     
                  #############                    
                 ##  ###########                   
                ###  ###### #####                  
                ### #######   ####                 
               ###  ########## ####                
              ####  ########### ####               
             ####   ###########  #####             
            #####   ### ########   #####           
           #####   ###   ########   ######         
          ######   ###  ###########   ######       
         ######   #### ##############  ######      
        #######  #####################  ######     
        #######  ######################  ######    
       #######  ###### #################  ######   
       #######  ###### ###### #########   ######   
       #######    ##  ######   ######     ######   
       #######        ######    #####     #####    
        ######        #####     #####     ####     
         #####        ####      #####     ###      
          #####       ###        ###      #        
            ###       ###        ###              
             ##       ###        ###               
    __________#_______####_______####______________
        身是菩提树,心如明镜台,时时勤拂拭,勿使惹尘埃。
                    我们的未来没有BUG              
    * ==============================================================================
    * Filename: ABConfig 
    * Created:  
    * Author:   WYC
    * Purpose:  
    * ==============================================================================
    */
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    [CreateAssetMenu(fileName = "ABConfig",menuName = "CreateABConfig",order = 0)]
    public class ABConfig : ScriptableObject {
    
        //单个文件夹所在文件夹路径,会遍历这个文件夹所有的Prefab,所有的Prefab名字不能重复,必须保证名字得唯一性
        public List<string> m_AllPrefabPath = new List<string>();
        public List<FileDirABName> m_AllFileDirAB = new List<FileDirABName>();
    
        [System.Serializable]
        public struct FileDirABName
        {
            public string ABName;
            public string Path;
        }
    }

    2. 打包加载 AssetBundle 

    /*              #########                       
                  ############                     
                  #############                    
                 ##  ###########                   
                ###  ###### #####                  
                ### #######   ####                 
               ###  ########## ####                
              ####  ########### ####               
             ####   ###########  #####             
            #####   ### ########   #####           
           #####   ###   ########   ######         
          ######   ###  ###########   ######       
         ######   #### ##############  ######      
        #######  #####################  ######     
        #######  ######################  ######    
       #######  ###### #################  ######   
       #######  ###### ###### #########   ######   
       #######    ##  ######   ######     ######   
       #######        ######    #####     #####    
        ######        #####     #####     ####     
         #####        ####      #####     ###      
          #####       ###        ###      #        
            ###       ###        ###              
             ##       ###        ###               
    __________#_______####_______####______________
        身是菩提树,心如明镜台,时时勤拂拭,勿使惹尘埃。
                    我们的未来没有BUG              
    * ==============================================================================
    * Filename: BundleEditor 
    * Created:  
    * Author:   WYC
    * Purpose:  打包加载 AssetBundle
    * ==============================================================================
    */
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEditor;
    using System.IO;
    using System.Xml.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    
    public class BundleEditor
    {
        private static string m_BunleTargetPath = Application.streamingAssetsPath;
        private static string ABCONGFIGPATH = "Assets/Editor/ABConfig.asset";
        //key是AB包名,value是路径,所有文件AB包dic
        private static Dictionary<string, string> m_AllFileDir = new Dictionary<string, string>();
        //过滤的list
        private static List<string> m_AllFileAB = new List<string>();
        //单个Prefab的AB包
        private static Dictionary<string, List<string>> m_AllPrefabDir = new Dictionary<string, List<string>>();
        //存储所有有效路径
        private static List<string> m_ConfigFile = new List<string>();
        //标签
        [MenuItem("Tools/AB打包")]
        public static void Build()
        {
            //AssetBundle打包设置
            m_AllFileAB.Clear();
            m_AllFileDir.Clear();
            m_AllPrefabDir.Clear();
            m_ConfigFile.Clear();
            ABConfig abconfig = AssetDatabase.LoadAssetAtPath<ABConfig>(ABCONGFIGPATH);
            foreach (ABConfig.FileDirABName f in abconfig.m_AllFileDirAB)
            {
                if (m_AllFileDir.ContainsKey(f.ABName))
                {
                    Debug.LogError("AB包配置名字重复,请检查!");
                }
                else
                {
                    m_AllFileDir.Add(f.ABName, f.Path);
                    m_AllFileAB.Add(f.Path);
                    m_ConfigFile.Add(f.Path);
                }
            }
            string[] allStr = AssetDatabase.FindAssets("t:Prefab", abconfig.m_AllPrefabPath.ToArray());//加载预设体
            for (int i = 0; i < allStr.Length; i++)
            {
                string path = AssetDatabase.GUIDToAssetPath(allStr[i]);
                //加载进度条
                EditorUtility.DisplayProgressBar("查找Prefab", "Prefab" + path, i * 1.0f / allStr.Length);
                m_ConfigFile.Add(path);
                if (!ContainAllFileAB(path))
                {
                    GameObject obj = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                    string[] allDepend = AssetDatabase.GetDependencies(path);
                    List<string> allDependPath = new List<string>();
                    for (int j = 0; j < allDepend.Length; j++)
                    {
                        //Debug.Log(allDepend[j]);
                        if (!ContainAllFileAB(allDepend[j]) && !allDepend[j].EndsWith(".cs"))
                        {
                            m_AllFileAB.Add(allDepend[j]);
                            allDependPath.Add(allDepend[j]);
                        }
                    }
                    if (m_AllPrefabDir.ContainsKey(obj.name))
                    {
                        Debug.LogError("存在相同名字的Prefab名字" + obj.name);
                    }
                    else
                    {
                        m_AllPrefabDir.Add(obj.name, allDependPath);
                    }
                }
            }
            foreach (string name in m_AllFileDir.Keys)
            {
                SetABName(name, m_AllFileDir[name]);
            }
            foreach (string name in m_AllPrefabDir.Keys)
            {
                SetABName(name, m_AllPrefabDir[name]);
            }
    
            BunildAssetBunble();
    
    
            //清除老的AB包设置
            string[] oldNameAB = AssetDatabase.GetAllAssetBundleNames();
            for (int i = 0; i < oldNameAB.Length; i++)
            {
                AssetDatabase.RemoveAssetBundleName(oldNameAB[i], true);
                EditorUtility.DisplayProgressBar("清除AB包名", "名字" + oldNameAB[i], i * 1.0f / oldNameAB.Length);
            }
    
            AssetDatabase.Refresh();//编辑器的刷新
            EditorUtility.ClearProgressBar();//清除进度条
    
        }
    
    
    
        //开始AB打包
        static void BunildAssetBunble()
        {
            string[] allBundles = AssetDatabase.GetAllAssetBundleNames();
            //key 为全路径 value为包名
            Dictionary<string, string> resPathDic = new Dictionary<string, string>();
            for (int i = 0; i < allBundles.Length; i++)
            {
                string[] allBundlePath = AssetDatabase.GetAssetPathsFromAssetBundle(allBundles[i]);
                for (int j = 0; j < allBundlePath.Length; j++)
                {
                    if (allBundlePath[j].EndsWith(".cs"))
                    {
                        continue;
                    }
                    Debug.Log("此AB包:" + allBundles[i] + "下面包含的资源文件路径:" + allBundlePath[j]);
                    if (ValidPath(allBundlePath[j]))
                    {
                        resPathDic.Add(allBundlePath[j], allBundles[i]);
                    }
                }
            }
    
            DeleteAB();
            WriteDate(resPathDic);
    
            BuildPipeline.BuildAssetBundles(m_BunleTargetPath, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
        }
        //生成自己的AB配置表
        static void WriteDate(Dictionary<string, string> resPathDic)
        {
            AssetBundleConfig config = new AssetBundleConfig();
            config.ABList = new List<ABBase>();
            foreach (string s in resPathDic.Keys)
            {
                ABBase aBBase = new ABBase();
                aBBase.Path = s;
                aBBase.Crc = CRC32.GetCRC32(s);
                aBBase.ABName = resPathDic[s];
                aBBase.AssetName = s.Remove(0, s.LastIndexOf("/") + 1);
                aBBase.ABDependce = new List<string>();
                string[] resDependce = AssetDatabase.GetDependencies(s);
                for (int i = 0; i < resDependce.Length; i++)
                {
                    string tempPath = resDependce[i];
                    if (tempPath == s || s.EndsWith(".cs"))
                    {
                        continue;
                    }
                    string abName = "";
                    if (resPathDic.TryGetValue(tempPath, out abName))
                    {
                        if (abName == resPathDic[s])
                        {
                            continue;
                        }
                        if (!aBBase.ABDependce.Contains(abName))
                        {
                            aBBase.ABDependce.Add(abName);
                        }
                    }
                }
                config.ABList.Add(aBBase);
            }
            //写入XML
            string xmlPath = Application.dataPath + "/Resources/XML/AssetBundleConfig.xml";
            if (File.Exists(xmlPath))
            {
                File.Delete(xmlPath);
            }
            using (FileStream fileStream = new FileStream(xmlPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                using (StreamWriter sw = new StreamWriter(fileStream, System.Text.Encoding.UTF8))
                {
                    XmlSerializer xml = new XmlSerializer(config.GetType());
                    xml.Serialize(sw, config);
                }
            }
            //写入二进制
            foreach (ABBase a in config.ABList)
            {
                a.Path = "";
            }
            string batysPath = Application.dataPath + "/Resources/Bytes/AssetBundleConfig.bytes";
            if (File.Exists(batysPath))
            {
                File.Delete(batysPath);
            }
            using (FileStream fileStream = new FileStream(batysPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fileStream, config);
            }
        }
    
        //删除多余的AB包资源
        static void DeleteAB()
        {
            string[] allBundlesName = AssetDatabase.GetAllAssetBundleNames();
            DirectoryInfo info = new DirectoryInfo(m_BunleTargetPath);
            FileInfo[] files = info.GetFiles("*", SearchOption.AllDirectories);
            for (int i = 0; i < files.Length; i++)
            {
                if (ConatinABName(files[i].Name, allBundlesName) || files[i].Name.EndsWith(".meta"))
                {
                    continue;
                }
                else
                {
                    Debug.Log("此AB包已经改名字了: " + files[i].Name);
                    if (File.Exists(files[i].FullName))
                    {
                        File.Delete(files[i].FullName);
                    }
                }
            }
        }
        static bool ConatinABName(string name, string[] strs)
        {
            for (int i = 0; i < strs.Length; i++)
            {
                if (name == strs[i])
                {
                    return true;
                }
            }
            return false;
        }
    
        //设置AB包名字
        static void SetABName(string name, string path)
        {
            AssetImporter assetImporter = AssetImporter.GetAtPath(path);
            if (assetImporter == null)
            {
                Debug.LogError("不存在的路径文件" + path);
            }
            else
            {
                assetImporter.assetBundleName = name;
            }
        }
        static void SetABName(string name, List<string> paths)
        {
            for (int i = 0; i < paths.Count; i++)
            {
                SetABName(name, paths[i]);
            }
        }
    
        //过滤的list  有没有重复的路径
        static bool ContainAllFileAB(string path)
        {
            for (int i = 0; i < m_AllFileAB.Count; i++)
            {
                if (path == m_AllFileAB[i] || (path.Contains(m_AllFileAB[i]) && (path.Replace(m_AllFileAB[i], "")[0] == '/')))
                {
                    return true;
                }
            }
            return false;
        }
    
        //是否有效路径
        static bool ValidPath(string path)
        {
            for (int i = 0; i < m_ConfigFile.Count; i++)
            {
                if (path.Contains(m_ConfigFile[i]))
                {
                    return true;
                }
            }
            return false;
        }
    }

    (注意以上2个脚本需要放在Editor文件夹里面)

    3、完善一下AB配置表类

    /*              #########                       
                  ############                     
                  #############                    
                 ##  ###########                   
                ###  ###### #####                  
                ### #######   ####                 
               ###  ########## ####                
              ####  ########### ####               
             ####   ###########  #####             
            #####   ### ########   #####           
           #####   ###   ########   ######         
          ######   ###  ###########   ######       
         ######   #### ##############  ######      
        #######  #####################  ######     
        #######  ######################  ######    
       #######  ###### #################  ######   
       #######  ###### ###### #########   ######   
       #######    ##  ######   ######     ######   
       #######        ######    #####     #####    
        ######        #####     #####     ####     
         #####        ####      #####     ###      
          #####       ###        ###      #        
            ###       ###        ###              
             ##       ###        ###               
    __________#_______####_______####______________
        身是菩提树,心如明镜台,时时勤拂拭,勿使惹尘埃。
                    我们的未来没有BUG              
    * ==============================================================================
    * Filename: AssetBundleConfig 
    * Created:  
    * Author:   WYC
    * Purpose:  
    * ==============================================================================
    */
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Xml.Serialization;
    
    
    [System.Serializable]
    public class AssetBundleConfig {
        [XmlElement("ABList")]
        public List<ABBase> ABList { get; set; }
    }
    [System.Serializable]
    public class ABBase
    {
        [XmlAttribute("Path")]
        public string Path { get; set; }
        [XmlAttribute("Crc")]
        public uint Crc { get; set; }
        [XmlAttribute("ABName")]
        public string ABName { get; set; }
        [XmlAttribute("AssetName")]
        public string AssetName { get; set; }
        [XmlElement("ABDependce")]
        public List<string> ABDependce { get; set; }
    }
    /*              #########                       
                  ############                     
                  #############                    
                 ##  ###########                   
                ###  ###### #####                  
                ### #######   ####                 
               ###  ########## ####                
              ####  ########### ####               
             ####   ###########  #####             
            #####   ### ########   #####           
           #####   ###   ########   ######         
          ######   ###  ###########   ######       
         ######   #### ##############  ######      
        #######  #####################  ######     
        #######  ######################  ######    
       #######  ###### #################  ######   
       #######  ###### ###### #########   ######   
       #######    ##  ######   ######     ######   
       #######        ######    #####     #####    
        ######        #####     #####     ####     
         #####        ####      #####     ###      
          #####       ###        ###      #        
            ###       ###        ###              
             ##       ###        ###               
    __________#_______####_______####______________
        身是菩提树,心如明镜台,时时勤拂拭,勿使惹尘埃。
                    我们的未来没有BUG              
    * ==============================================================================
    * Filename: CRC32 
    * Created:  
    * Author:   WYC
    * Purpose:  
    * ==============================================================================
    */
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class CRC32 {
        //crc表
        static UInt32[] crcTable =
        {
              0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
              0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
              0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
              0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
              0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
              0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
              0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
              0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
              0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
              0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
              0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
              0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
              0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
              0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
              0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
              0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
              0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
              0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
              0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
              0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
              0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
              0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
              0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
              0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
              0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
              0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
              0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
              0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
              0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
              0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
              0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
              0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
            };
    
        //返回字符串的crc
        public static uint GetCRC32(string msg)
        {
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(msg);
            int iCount = bytes.Length;
            uint crc = 0xFFFFFFFF;
            for (int i = 0; i < iCount; i++)
            {
                crc = (crc << 8) ^ crcTable[(crc >> 24) ^ bytes[i]];
            }
            return crc;
        }
    }

    4.先工具栏初始化运行 Tool/AB打包   然后反序列化加载  测试代码如下

     void TextLoadAB()
        {
            TextAsset textAsset = Resources.Load<TextAsset>("Bytes/AssetBundleConfig");
            using (MemoryStream stream = new MemoryStream(textAsset.bytes))
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                AssetBundleConfig textSerilize = (AssetBundleConfig)binaryFormatter.Deserialize(stream);
                string path = "Assets/GameData/Prefabs/Attack.prefab";
                uint crc = CRC32.GetCRC32(path);
                Debug.Log(textSerilize.ABList.Count);
                ABBase aBBase = null;
               
                for (int i = 0; i < textSerilize.ABList.Count; i++)
                {
                 
                    if (textSerilize.ABList[i].Crc == crc)
                    {
                        aBBase = textSerilize.ABList[i];
                    }
                    Debug.Log(textSerilize.ABList[i].Path);
                }
    
                for (int i = 0; i < aBBase.ABDependce.Count; i++)
                {
                    Debug.Log(aBBase.ABDependce[i]);
                    AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + aBBase.ABDependce[i]);
                }
                AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + aBBase.ABName);
                GameObject obj = GameObject.Instantiate(assetBundle.LoadAsset<GameObject>(aBBase.ABName));
            }
        }
    

      

  • 相关阅读:
    Html禁止粘贴 复制 剪切
    表单标签
    自构BeanHandler(用BeansUtils)
    spring配置中引入properties
    How Subcontracting Cockpit ME2ON creates SD delivery?
    cascadia code一款很好看的微软字体
    How condition value calculated in sap
    Code in SAP query
    SO Pricing not updated for partial billing items
    Javascript learning
  • 原文地址:https://www.cnblogs.com/mclll520/p/10132834.html
Copyright © 2011-2022 走看看